home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Utilities / vim-5.1 / src / memline.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-24  |  92.6 KB  |  3,545 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. /* for debugging */
  10. /* #define CHECK(c, s)    if (c) EMSG(s) */
  11. #define CHECK(c, s)
  12.  
  13. /*
  14.  * memline.c: Contains the functions for appending, deleting and changing the
  15.  * text lines. The memfile functions are used to store the information in blocks
  16.  * of memory, backed up by a file. The structure of the information is a tree.
  17.  * The root of the tree is a pointer block. The leaves of the tree are data
  18.  * blocks. In between may be several layers of pointer blocks, forming branches.
  19.  *
  20.  * Three types of blocks are used:
  21.  * - Block nr 0 contains information for recovery
  22.  * - Pointer blocks contain list of pointers to other blocks.
  23.  * - Data blocks contain the actual text.
  24.  *
  25.  * Block nr 0 contains the block0 structure (see below).
  26.  *
  27.  * Block nr 1 is the first pointer block. It is the root of the tree.
  28.  * Other pointer blocks are branches.
  29.  *
  30.  *  If a line is too big to fit in a single page, the block containing that
  31.  *  line is made big enough to hold the line. It may span several pages.
  32.  *  Otherwise all blocks are one page.
  33.  *
  34.  *  A data block that was filled when starting to edit a file and was not
  35.  *  changed since then, can have a negative block number. This means that it
  36.  *  has not yet been assigned a place in the file. When recovering, the lines
  37.  *  in this data block can be read from the original file. When the block is
  38.  *  changed (lines appended/deleted/changed) or when it is flushed it gets a
  39.  *  positive number. Use mf_trans_del() to get the new number, before calling
  40.  *  mf_get().
  41.  */
  42.  
  43. #if defined MSDOS  ||  defined WIN32
  44. # include <io.h>
  45. #endif
  46.  
  47. #include "vim.h"
  48.  
  49. #ifdef HAVE_FCNTL_H
  50. # include <fcntl.h>
  51. #endif
  52. #ifndef UNIX        /* it's in os_unix.h for Unix */
  53. # include <time.h>
  54. #endif
  55.  
  56. #ifdef SASC
  57. # include <proto/dos.h>        /* for Open() and Close() */
  58. #endif
  59.  
  60. typedef struct block0        ZERO_BL;    /* contents of the first block */
  61. typedef struct pointer_block    PTR_BL;        /* contents of a pointer block */
  62. typedef struct data_block    DATA_BL;    /* contents of a data block */
  63. typedef struct pointer_entry    PTR_EN;        /* block/line-count pair */
  64.  
  65. #define DATA_ID        (('d' << 8) + 'a')        /* data block id */
  66. #define PTR_ID        (('p' << 8) + 't')        /* pointer block id */
  67. #define BLOCK0_ID0  'b'                /* block 0 id 0 */
  68. #define BLOCK0_ID1  '0'                /* block 0 id 1 */
  69.  
  70. /*
  71.  * pointer to a block, used in a pointer block
  72.  */
  73. struct pointer_entry
  74. {
  75.     blocknr_t    pe_bnum;    /* block number */
  76.     linenr_t    pe_line_count;    /* number of lines in this branch */
  77.     linenr_t    pe_old_lnum;    /* lnum for this block (for recovery) */
  78.     int        pe_page_count;    /* number of pages in block pe_bnum */
  79. };
  80.  
  81. /*
  82.  * A pointer block contains a list of branches in the tree.
  83.  */
  84. struct pointer_block
  85. {
  86.     short_u    pb_id;        /* ID for pointer block: PTR_ID */
  87.     short_u    pb_count;    /* number of pointer in this block */
  88.     short_u    pb_count_max;    /* maximum value for pb_count */
  89.     PTR_EN    pb_pointer[1];    /* list of pointers to blocks (actually longer)
  90.                  * followed by empty space until end of page */
  91. };
  92.  
  93. /*
  94.  * A data block is a leaf in the tree.
  95.  *
  96.  * The text of the lines is at the end of the block. The text of the first line
  97.  * in the block is put at the end, the text of the second line in front of it,
  98.  * etc. Thus the order of the lines is the opposite of the line number.
  99.  */
  100. struct data_block
  101. {
  102.     short_u    db_id;        /* ID for data block: DATA_ID */
  103.     unsigned    db_free;    /* free space available */
  104.     unsigned    db_txt_start;    /* byte where text starts */
  105.     unsigned    db_txt_end;    /* byte just after data block */
  106.     linenr_t    db_line_count;    /* number of lines in this block */
  107.     unsigned    db_index[1];    /* index for start of line (actually bigger)
  108.                  * followed by empty space upto db_txt_start
  109.                  * followed by the text in the lines until
  110.                  * end of page */
  111. };
  112.  
  113. /*
  114.  * The low bits of db_index hold the actual index. The topmost bit is
  115.  * used for the global command to be able to mark a line.
  116.  * This method is not clean, but otherwise there would be at least one extra
  117.  * byte used for each line.
  118.  * The mark has to be in this place to keep it with the correct line when other
  119.  * lines are inserted or deleted.
  120.  */
  121. #define DB_MARKED    ((unsigned)1 << ((sizeof(unsigned) * 8) - 1))
  122. #define DB_INDEX_MASK    (~DB_MARKED)
  123.  
  124. #define INDEX_SIZE  (sizeof(unsigned))        /* size of one db_index entry */
  125. #define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE)  /* size of data block header */
  126.  
  127. #define B0_FNAME_SIZE    900
  128. #define B0_UNAME_SIZE    40
  129. #define B0_HNAME_SIZE    40
  130. /*
  131.  * Restrict the numbers to 32 bits, otherwise most compilers will complain.
  132.  * This won't detect a 64 bit machine that only swaps a byte in the top 32
  133.  * bits, but that is crazy anyway.
  134.  */
  135. #define B0_MAGIC_LONG    0x30313233
  136. #define B0_MAGIC_INT    0x20212223
  137. #define B0_MAGIC_SHORT    0x10111213
  138. #define B0_MAGIC_CHAR    0x55
  139.  
  140. /*
  141.  * Block zero holds all info about the swap file.
  142.  *
  143.  * NOTE: DEFINITION OF BLOCK 0 SHOULD NOT CHANGE, it makes all existing swap
  144.  * files unusable!
  145.  *
  146.  * If size of block0 changes anyway, adjust minimal block size
  147.  * in mf_open()!!
  148.  *
  149.  * This block is built up of single bytes, to make it portable accros
  150.  * different machines. b0_magic_* is used to check the byte order and size of
  151.  * variables, because the rest of the swap is not portable.
  152.  */
  153. struct block0
  154. {
  155.     char_u    b0_id[2];    /* id for block 0: BLOCK0_ID0 and BLOCK0_ID1 */
  156.     char_u    b0_version[10];    /* Vim version string */
  157.     char_u    b0_page_size[4];/* number of bytes per page */
  158.     char_u    b0_mtime[4];    /* last modification time of file */
  159.     char_u    b0_ino[4];    /* inode of b0_fname */
  160.     char_u    b0_pid[4];    /* process id of creator (or 0) */
  161.     char_u    b0_uname[B0_UNAME_SIZE]; /* name of user (uid if no name) */
  162.     char_u    b0_hname[B0_HNAME_SIZE]; /* host name (if it has a name) */
  163.     char_u    b0_fname[B0_FNAME_SIZE]; /* name of file being edited */
  164.     long    b0_magic_long;    /* check for byte order of long */
  165.     int        b0_magic_int;    /* check for byte order of int */
  166.     short    b0_magic_short;    /* check for byte order of short */
  167.     char_u    b0_magic_char;    /* check for last char */
  168. };
  169.  
  170. #define STACK_INCR    5    /* nr of entries added to ml_stack at a time */
  171.  
  172. /*
  173.  * The line number where the first mark may be is remembered.
  174.  * If it is 0 there are no marks at all.
  175.  * (always used for the current buffer only, no buffer change possible while
  176.  * executing a global command).
  177.  */
  178. static linenr_t    lowest_marked = 0;
  179.  
  180. /*
  181.  * arguments for ml_find_line()
  182.  */
  183. #define ML_DELETE    0x11        /* delete line */
  184. #define ML_INSERT    0x12        /* insert line */
  185. #define ML_FIND        0x13        /* just find the line */
  186. #define ML_FLUSH    0x02        /* flush locked block */
  187. #define ML_SIMPLE(x)    (x & 0x10)  /* DEL, INS or FIND */
  188.  
  189. static void set_b0_fname __ARGS((ZERO_BL *, BUF *buf));
  190. static void swapfile_info __ARGS((char_u *));
  191. static int recov_file_names __ARGS((char_u **, char_u *, int prepend_dot));
  192. static int ml_append_int __ARGS((BUF *, linenr_t, char_u *, colnr_t, int, int));
  193. static int ml_delete_int __ARGS((BUF *, linenr_t, int));
  194. static char_u *findswapname __ARGS((BUF *, char_u **, char_u *));
  195. static void ml_flush_line __ARGS((BUF *));
  196. static BHDR *ml_new_data __ARGS((MEMFILE *, int, int));
  197. static BHDR *ml_new_ptr __ARGS((MEMFILE *));
  198. static BHDR *ml_find_line __ARGS((BUF *, linenr_t, int));
  199. static int ml_add_stack __ARGS((BUF *));
  200. static char_u *makeswapname __ARGS((BUF *, char_u *));
  201. static void ml_lineadd __ARGS((BUF *, int));
  202. static int b0_magic_wrong __ARGS((ZERO_BL *));
  203. #ifdef CHECK_INODE
  204. static int fnamecmp_ino __ARGS((char_u *, char_u *, long));
  205. #endif
  206. static void long_to_char __ARGS((long, char_u *));
  207. static long char_to_long __ARGS((char_u *));
  208.  
  209. /*
  210.  * open a new memline for 'curbuf'
  211.  *
  212.  * return FAIL for failure, OK otherwise
  213.  */
  214.     int
  215. ml_open()
  216. {
  217.     MEMFILE    *mfp;
  218.     BHDR    *hp = NULL;
  219.     ZERO_BL    *b0p;
  220.     PTR_BL    *pp;
  221.     DATA_BL    *dp;
  222.  
  223. /*
  224.  * init fields in memline struct
  225.  */
  226.     curbuf->b_ml.ml_stack_size = 0;    /* no stack yet */
  227.     curbuf->b_ml.ml_stack = NULL;    /* no stack yet */
  228.     curbuf->b_ml.ml_stack_top = 0;    /* nothing in the stack */
  229.     curbuf->b_ml.ml_locked = NULL;    /* no cached block */
  230.     curbuf->b_ml.ml_line_lnum = 0;    /* no cached line */
  231.  
  232. /*
  233.  * When 'updatecount' is non-zero, flag that a swap file may be opened later.
  234.  */
  235.     if (p_uc)
  236.     curbuf->b_may_swap = TRUE;
  237.  
  238. /*
  239.  * Open the memfile.  No swap file is created yet.
  240.  */
  241.     mfp = mf_open(NULL, TRUE);
  242.     if (mfp == NULL)
  243.     goto error;
  244.  
  245. #if defined(MSDOS) && !defined(DJGPP)
  246.     /* for 16 bit MS-DOS create a swapfile now, because we run out of
  247.      * memory very quickly */
  248.     if (p_uc)
  249.     ml_open_file(curbuf);
  250. #endif
  251.  
  252.     curbuf->b_ml.ml_mfp = mfp;
  253.     curbuf->b_ml.ml_flags = ML_EMPTY;
  254.     curbuf->b_ml.ml_line_count = 1;
  255.  
  256. /*
  257.  * fill block0 struct and write page 0
  258.  */
  259.     if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
  260.     goto error;
  261.     if (hp->bh_bnum != 0)
  262.     {
  263.     EMSG("didn't get block nr 0?");
  264.     goto error;
  265.     }
  266.     b0p = (ZERO_BL *)(hp->bh_data);
  267.  
  268.     b0p->b0_id[0] = BLOCK0_ID0;
  269.     b0p->b0_id[1] = BLOCK0_ID1;
  270.     b0p->b0_magic_long = (long)B0_MAGIC_LONG;
  271.     b0p->b0_magic_int = (int)B0_MAGIC_INT;
  272.     b0p->b0_magic_short = (short)B0_MAGIC_SHORT;
  273.     b0p->b0_magic_char = B0_MAGIC_CHAR;
  274.  
  275.     STRNCPY(b0p->b0_version, "VIM ", 4);
  276.     STRNCPY(b0p->b0_version + 4, Version, 6);
  277.     set_b0_fname(b0p, curbuf);
  278.     long_to_char((long)mfp->mf_page_size, b0p->b0_page_size);
  279.     (void)mch_get_user_name(b0p->b0_uname, B0_UNAME_SIZE);
  280.     b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL;
  281.     mch_get_host_name(b0p->b0_hname, B0_HNAME_SIZE);
  282.     b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL;
  283.     long_to_char(mch_get_pid(), b0p->b0_pid);
  284.  
  285.     /*
  286.      * Always sync block number 0 to disk, so we can check the file name in
  287.      * the swap file in findswapname(). Don't do this for help files though.
  288.      * Only works when there's a swapfile, otherwise it's done when the file
  289.      * is created.
  290.      */
  291.     mf_put(mfp, hp, TRUE, FALSE);
  292.     if (!curbuf->b_help)
  293.     (void)mf_sync(mfp, 0);
  294.  
  295. /*
  296.  * fill in root pointer block and write page 1
  297.  */
  298.     if ((hp = ml_new_ptr(mfp)) == NULL)
  299.     goto error;
  300.     if (hp->bh_bnum != 1)
  301.     {
  302.     EMSG("didn't get block nr 1?");
  303.     goto error;
  304.     }
  305.     pp = (PTR_BL *)(hp->bh_data);
  306.     pp->pb_count = 1;
  307.     pp->pb_pointer[0].pe_bnum = 2;
  308.     pp->pb_pointer[0].pe_page_count = 1;
  309.     pp->pb_pointer[0].pe_old_lnum = 1;
  310.     pp->pb_pointer[0].pe_line_count = 1;    /* line count after insertion */
  311.     mf_put(mfp, hp, TRUE, FALSE);
  312.  
  313. /*
  314.  * allocate first data block and create an empty line 1.
  315.  */
  316.     if ((hp = ml_new_data(mfp, FALSE, 1)) == NULL)
  317.     goto error;
  318.     if (hp->bh_bnum != 2)
  319.     {
  320.     EMSG("didn't get block nr 2?");
  321.     goto error;
  322.     }
  323.  
  324.     dp = (DATA_BL *)(hp->bh_data);
  325.     dp->db_index[0] = --dp->db_txt_start;    /* at end of block */
  326.     dp->db_free -= 1 + INDEX_SIZE;
  327.     dp->db_line_count = 1;
  328.     *((char_u *)dp + dp->db_txt_start) = NUL;    /* emtpy line */
  329.  
  330.     return OK;
  331.  
  332. error:
  333.     if (mfp != NULL)
  334.     {
  335.     if (hp)
  336.         mf_put(mfp, hp, FALSE, FALSE);
  337.     mf_close(mfp, TRUE);        /* will also free(mfp->mf_fname) */
  338.     }
  339.     curbuf->b_ml.ml_mfp = NULL;
  340.     return FAIL;
  341. }
  342.  
  343. /*
  344.  * ml_setname() is called when the file name has been changed.
  345.  * It may rename the swap file.
  346.  */
  347.     void
  348. ml_setname()
  349. {
  350.     int        success = FALSE;
  351.     MEMFILE    *mfp;
  352.     char_u    *fname;
  353.     char_u    *dirp;
  354. #if defined(MSDOS) || defined(WIN32)
  355.     char_u    *p;
  356. #endif
  357.  
  358. /*
  359.  * When 'updatecount' is 0 there is never a swap file.
  360.  * For help files we will make a swap file now.
  361.  */
  362.     if (p_uc == 0)
  363.     return;
  364.  
  365.     mfp = curbuf->b_ml.ml_mfp;
  366.     if (mfp->mf_fd < 0)            /* there is no swap file yet */
  367.     {
  368.     ml_open_file(curbuf);        /* create a swap file */
  369.     return;
  370.     }
  371.  
  372. /*
  373.  * Try all directories in the 'directory' option.
  374.  */
  375.     dirp = p_dir;
  376.     for (;;)
  377.     {
  378.     if (*dirp == NUL)        /* tried all directories, fail */
  379.         break;
  380.     fname = findswapname(curbuf, &dirp, mfp->mf_fname); /* alloc's fname */
  381.     if (fname == NULL)        /* no file name found for this dir */
  382.         continue;
  383.  
  384. #if defined(MSDOS) || defined(WIN32)
  385.     /*
  386.      * Set full pathname for swap file now, because a ":!cd dir" may
  387.      * change directory without us knowing it.
  388.      */
  389.     p = FullName_save(fname, FALSE);
  390.     vim_free(fname);
  391.     fname = p;
  392.     if (fname == NULL)
  393.         continue;
  394. #endif
  395.         /* if the file name is the same we don't have to do anything */
  396.     if (fnamecmp(fname, mfp->mf_fname) == 0)
  397.     {
  398.         vim_free(fname);
  399.         success = TRUE;
  400.         break;
  401.     }
  402.         /* need to close the swap file before renaming */
  403.     if (mfp->mf_fd >= 0)
  404.     {
  405.         close(mfp->mf_fd);
  406.         mfp->mf_fd = -1;
  407.     }
  408.  
  409.         /* try to rename the swap file */
  410.     if (vim_rename(mfp->mf_fname, fname) == 0)
  411.     {
  412.         success = TRUE;
  413.         vim_free(mfp->mf_fname);
  414.         mfp->mf_fname = fname;
  415.         vim_free(mfp->mf_ffname);
  416. #if defined(MSDOS) || defined(WIN32)
  417.         mfp->mf_ffname = NULL;  /* mf_fname is full pathname already */
  418. #else
  419.         mf_set_ffname(mfp);
  420. #endif
  421.         break;
  422.     }
  423.     vim_free(fname);        /* this fname didn't work, try another */
  424.     }
  425.  
  426.     if (mfp->mf_fd == -1)        /* need to (re)open the swap file */
  427.     {
  428.     mfp->mf_fd = open((char *)mfp->mf_fname, O_RDWR | O_EXTRA);
  429.     if (mfp->mf_fd < 0)
  430.     {
  431.         /* could not (re)open the swap file, what can we do???? */
  432.         EMSG("Oops, lost the swap file!!!");
  433.         return;
  434.     }
  435.     }
  436.     if (!success)
  437.     EMSG("Could not rename swap file");
  438. }
  439.  
  440. /*
  441.  * Open a file for the memfile for all buffers that are not readonly or have
  442.  * been modified.
  443.  * Used when 'updatecount' changes from zero to non-zero.
  444.  */
  445.     void
  446. ml_open_files()
  447. {
  448.     BUF        *buf;
  449.  
  450.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  451.     if (!buf->b_p_ro || buf->b_changed)
  452.         ml_open_file(buf);
  453. }
  454.  
  455. /*
  456.  * Open a swap file for an existing memfile, if there is no swap file yet.
  457.  * If we are unable to find a file name, mf_fname will be NULL
  458.  * and the memfile will be in memory only (no recovery possible).
  459.  */
  460.     void
  461. ml_open_file(buf)
  462.     BUF        *buf;
  463. {
  464.     MEMFILE    *mfp;
  465.     char_u    *fname;
  466.     char_u    *dirp;
  467.  
  468.     mfp = buf->b_ml.ml_mfp;
  469.     if (mfp == NULL || mfp->mf_fd >= 0)        /* nothing to do */
  470.     return;
  471.  
  472.     /*
  473.      * Try all directories in 'directory' option.
  474.      */
  475.     dirp = p_dir;
  476.     for (;;)
  477.     {
  478.     if (*dirp == NUL)
  479.         break;
  480.     fname = findswapname(buf, &dirp, NULL);    /* allocates fname */
  481.     if (fname == NULL)
  482.         continue;
  483.     if (mf_open_file(mfp, fname) == OK)    /* consumes fname! */
  484.         break;
  485.     }
  486.  
  487.     if (mfp->mf_fname == NULL)        /* Failed! */
  488.     {
  489.     need_wait_return = TRUE;    /* call wait_return later */
  490.     ++no_wait_return;
  491.     (void)EMSG2("Unable to open swap file for \"%s\", recovery impossible",
  492.            buf->b_fname == NULL ? (char_u *)"No File" : buf->b_fname);
  493.     --no_wait_return;
  494.     }
  495.     else
  496.     {
  497. #if defined(MSDOS) || defined(WIN32)
  498.     /*
  499.      * set full pathname for swap file now, because a ":!cd dir" may
  500.      * change directory without us knowing it.
  501.      */
  502.     mf_fullname(mfp);
  503. #endif
  504.     /* Flush block zero, so others can read it */
  505.     (void)mf_sync(mfp, MFS_ZERO);
  506.     }
  507.  
  508.     /* don't try to open a swap file again */
  509.     buf->b_may_swap = FALSE;
  510. }
  511.  
  512. /*
  513.  * If still need to create a swap file, and starting to edit a not-readonly
  514.  * file, or reading into an existing buffer, create a swap file now.
  515.  */
  516.     void
  517. check_need_swap(newfile)
  518.     int        newfile;        /* reading file into new buffer */
  519. {
  520.     if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile))
  521.     ml_open_file(curbuf);
  522. }
  523.  
  524. /*
  525.  * Close memline for buffer 'buf'.
  526.  * If 'del_file' is TRUE, delete the swap file
  527.  */
  528.     void
  529. ml_close(buf, del_file)
  530.     BUF        *buf;
  531.     int        del_file;
  532. {
  533.     if (buf->b_ml.ml_mfp == NULL)        /* not open */
  534.     return;
  535.     mf_close(buf->b_ml.ml_mfp, del_file);        /* close the .swp file */
  536.     if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY))
  537.     vim_free(buf->b_ml.ml_line_ptr);
  538.     vim_free(buf->b_ml.ml_stack);
  539.     buf->b_ml.ml_mfp = NULL;
  540. }
  541.  
  542. /*
  543.  * Close all existing memlines and memfiles.
  544.  * Used when exiting.
  545.  * When 'del_file' is TRUE, delete the memfiles.
  546.  */
  547.     void
  548. ml_close_all(del_file)
  549.     int        del_file;
  550. {
  551.     BUF        *buf;
  552.  
  553.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  554.     ml_close(buf, del_file);
  555. }
  556.  
  557. /*
  558.  * Close all memfiles for not modified buffers.
  559.  * Only use just before exiting!
  560.  */
  561.     void
  562. ml_close_notmod()
  563. {
  564.     BUF        *buf;
  565.  
  566.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  567.     if (!buf_changed(buf))
  568.         ml_close(buf, TRUE);    /* close all not-modified buffers */
  569. }
  570.  
  571. /*
  572.  * Update the timestamp in the .swp file.
  573.  * Used when the file has been written.
  574.  */
  575.     void
  576. ml_timestamp(buf)
  577.     BUF        *buf;
  578. {
  579.     MEMFILE    *mfp;
  580.     BHDR    *hp;
  581.     ZERO_BL    *b0p;
  582.  
  583.     mfp = buf->b_ml.ml_mfp;
  584.  
  585.     if (mfp == NULL || (hp = mf_get(mfp, (blocknr_t)0, 1)) == NULL)
  586.     return;
  587.     b0p = (ZERO_BL *)(hp->bh_data);
  588.     if (b0p->b0_id[0] != BLOCK0_ID0 || b0p->b0_id[1] != BLOCK0_ID1)
  589.     EMSG("ml_timestamp: Didn't get block 0??");
  590.     else
  591.     set_b0_fname(b0p, buf);
  592.     mf_put(mfp, hp, TRUE, FALSE);
  593. }
  594.  
  595. /*
  596.  * Write file name and timestamp into block 0 of a swap file.
  597.  * Also set buf->b_mtime.
  598.  * Don't use NameBuff[]!!!
  599.  */
  600.     static void
  601. set_b0_fname(b0p, buf)
  602.     ZERO_BL    *b0p;
  603.     BUF        *buf;
  604. {
  605.     struct stat    st;
  606.     size_t    flen, ulen;
  607.     char_u    uname[B0_UNAME_SIZE];
  608.  
  609.     if (buf->b_ffname == NULL)
  610.     b0p->b0_fname[0] = NUL;
  611.     else
  612.     {
  613.     /*
  614.      * For a file under the home directory of the current user, we try to
  615.      * replace the home directory path with "~user". This helps when
  616.      * editing the same file on different machines over a network.
  617.      * First replace home dir path with "~/" with home_replace().
  618.      * Then insert the user name to get "~user/".
  619.      */
  620.     home_replace(NULL, buf->b_ffname, b0p->b0_fname, B0_FNAME_SIZE);
  621.     if (b0p->b0_fname[0] == '~')
  622.     {
  623.         flen = STRLEN(b0p->b0_fname);
  624.         /* If there is no user name or it is too long, don't use "~/" */
  625.         if (mch_get_user_name(uname, B0_UNAME_SIZE) == FAIL ||
  626.              (ulen = STRLEN(uname)) + flen > B0_FNAME_SIZE - 1)
  627.         STRNCPY(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE);
  628.         else
  629.         {
  630.         vim_memmove(b0p->b0_fname + ulen + 1, b0p->b0_fname + 1, flen);
  631.         vim_memmove(b0p->b0_fname + 1, uname, ulen);
  632.         }
  633.     }
  634.     if (stat((char *)buf->b_ffname, &st) >= 0)
  635.     {
  636.         long_to_char((long)st.st_mtime, b0p->b0_mtime);
  637. #ifdef CHECK_INODE
  638.         long_to_char((long)st.st_ino, b0p->b0_ino);
  639. #endif
  640.         buf->b_mtime = st.st_mtime;
  641.         buf->b_mtime_read = st.st_mtime;
  642.     }
  643.     else
  644.     {
  645.         long_to_char(0L, b0p->b0_mtime);
  646. #ifdef CHECK_INODE
  647.         long_to_char(0L, b0p->b0_ino);
  648. #endif
  649.         buf->b_mtime = 0;
  650.         buf->b_mtime_read = 0;
  651.     }
  652.     }
  653. }
  654.  
  655. /*
  656.  * try to recover curbuf from the .swp file
  657.  */
  658.     void
  659. ml_recover()
  660. {
  661.     BUF        *buf = NULL;
  662.     MEMFILE    *mfp = NULL;
  663.     char_u    *fname;
  664.     BHDR    *hp = NULL;
  665.     ZERO_BL    *b0p;
  666.     PTR_BL    *pp;
  667.     DATA_BL    *dp;
  668.     IPTR    *ip;
  669.     blocknr_t    bnum;
  670.     int        page_count;
  671.     struct stat    org_stat, swp_stat;
  672.     int        len;
  673.     int        directly;
  674.     linenr_t    lnum;
  675.     char_u    *p;
  676.     int        i;
  677.     long    error;
  678.     int        cannot_open;
  679.     linenr_t    line_count;
  680.     int        has_error;
  681.     int        idx;
  682.     int        top;
  683.     int        txt_start;
  684.     off_t    size;
  685.     int        called_from_main;
  686.     int        serious_error = TRUE;
  687.     long    mtime;
  688.     int        attr;
  689.  
  690.     called_from_main = (curbuf->b_ml.ml_mfp == NULL);
  691.     attr = highlight_attr[HLF_E];
  692. /*
  693.  * If the file name ends in ".sw?" we use it directly.
  694.  * Otherwise a search is done to find the swap file(s).
  695.  */
  696.     fname = curbuf->b_fname;
  697.     if (fname == NULL)            /* When there is no file name */
  698.     fname = (char_u *)"";
  699.     len = STRLEN(fname);
  700.     if (len >= 4 && STRNICMP(fname + len - 4, ".sw", 3) == 0)
  701.     {
  702.     directly = TRUE;
  703.     fname = vim_strsave(fname); /* make a copy for mf_open */
  704.     }
  705.     else
  706.     {
  707.     directly = FALSE;
  708.  
  709.     /* count the number of matching swap files */
  710.     len = recover_names(&fname, FALSE, 0);
  711.     if (len == 0)            /* no swap files found */
  712.     {
  713.         EMSG2("No swap file found for %s", fname);
  714.         goto theend;
  715.     }
  716.     if (len == 1)            /* one swap file found, use it */
  717.         i = 1;
  718.     else                /* several swap files found, choose */
  719.     {
  720.         /* list the names of the swap files */
  721.         (void)recover_names(&fname, TRUE, 0);
  722.         msg_putchar('\n');
  723.         MSG_PUTS("Enter number of swap file to use (0 to quit): ");
  724.         i = get_number(FALSE);
  725.         if (i < 1 || i > len)
  726.         goto theend;
  727.     }
  728.     /* get the swap file name that will be used */
  729.     (void)recover_names(&fname, FALSE, i);
  730.     }
  731.     if (fname == NULL)
  732.     goto theend;            /* out of memory */
  733.  
  734.     /* When called from main() still need to initialize storage structure */
  735.     if (called_from_main && ml_open() == FAIL)
  736.     getout(1);
  737.  
  738. /*
  739.  * allocate a buffer structure (only the memline in it is really used)
  740.  */
  741.     buf = (BUF *)alloc((unsigned)sizeof(BUF));
  742.     if (buf == NULL)
  743.     {
  744.     vim_free(fname);
  745.     goto theend;
  746.     }
  747.  
  748. /*
  749.  * init fields in memline struct
  750.  */
  751.     buf->b_ml.ml_stack_size = 0;    /* no stack yet */
  752.     buf->b_ml.ml_stack = NULL;        /* no stack yet */
  753.     buf->b_ml.ml_stack_top = 0;        /* nothing in the stack */
  754.     buf->b_ml.ml_line_lnum = 0;        /* no cached line */
  755.     buf->b_ml.ml_locked = NULL;        /* no locked block */
  756.     buf->b_ml.ml_flags = 0;
  757.  
  758. /*
  759.  * open the memfile from the old swap file
  760.  */
  761.     p = vim_strsave(fname);        /* save fname for the message */
  762.     mfp = mf_open(fname, FALSE);    /* consumes fname! */
  763.     if (mfp == NULL || mfp->mf_fd < 0)
  764.     {
  765.     if (p != NULL)
  766.     {
  767.         EMSG2("Cannot open %s", p);
  768.         vim_free(p);
  769.     }
  770.     goto theend;
  771.     }
  772.     vim_free(p);
  773.     buf->b_ml.ml_mfp = mfp;
  774.  
  775. /*
  776.  * try to read block 0
  777.  */
  778.     if ((hp = mf_get(mfp, (blocknr_t)0, 1)) == NULL)
  779.     {
  780.     msg_start();
  781.     MSG_PUTS_ATTR("Unable to read block 0 from ", attr);
  782.     msg_outtrans_attr(mfp->mf_fname, attr);
  783.     MSG_PUTS_ATTR(
  784.         "\nMaybe no changes were made or Vim did not update the swap file",
  785.         attr);
  786.     msg_end();
  787.     goto theend;
  788.     }
  789.     b0p = (ZERO_BL *)(hp->bh_data);
  790.     if (STRNCMP(b0p->b0_version, "VIM 3.0", 7) == 0)
  791.     {
  792.     msg_start();
  793.     MSG_PUTS("The file ");
  794.     msg_outtrans(mfp->mf_fname);
  795.     MSG_PUTS(" cannot be used with this version of Vim.\n");
  796.     MSG_PUTS("Use Vim version 3.0.\n");
  797.     msg_end();
  798.     goto theend;
  799.     }
  800.     if (b0p->b0_id[0] != BLOCK0_ID0 || b0p->b0_id[1] != BLOCK0_ID1)
  801.     {
  802.     EMSG2("%s is not a swap file", mfp->mf_fname);
  803.     goto theend;
  804.     }
  805.     if (b0_magic_wrong(b0p))
  806.     {
  807.     msg_start();
  808.     MSG_PUTS_ATTR("The file ", attr);
  809.     msg_outtrans_attr(mfp->mf_fname, attr);
  810. #if defined(MSDOS) || defined(WIN32)
  811.     if (STRNCMP(b0p->b0_hname, "PC ", 3) == 0)
  812.         MSG_PUTS_ATTR(" cannot be used with this version of Vim.\n", attr);
  813.     else
  814. #endif
  815.         MSG_PUTS_ATTR(" cannot be used on this computer.\n", attr);
  816.     MSG_PUTS_ATTR("The file was created on ", attr);
  817.         /* avoid going past the end of currupted hostname */
  818.     b0p->b0_fname[0] = NUL;
  819.     MSG_PUTS_ATTR(b0p->b0_hname, attr);
  820.     MSG_PUTS_ATTR(",\nor the file has been damaged.", attr);
  821.     msg_end();
  822.     goto theend;
  823.     }
  824.     /*
  825.      * If we guessed the wrong page size, we have to recalculate the
  826.      * highest block number in the file.
  827.      */
  828.     if (mfp->mf_page_size != (unsigned)char_to_long(b0p->b0_page_size))
  829.     {
  830.     mfp->mf_page_size = (unsigned)char_to_long(b0p->b0_page_size);
  831.     if ((size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
  832.         mfp->mf_blocknr_max = 0;        /* no file or empty file */
  833.     else
  834.         mfp->mf_blocknr_max = size / mfp->mf_page_size;
  835.     mfp->mf_infile_count = mfp->mf_blocknr_max;
  836.     }
  837.  
  838. /*
  839.  * If .swp file name given directly, use name from swap file for buffer.
  840.  */
  841.     if (directly)
  842.     {
  843.     expand_env(b0p->b0_fname, NameBuff, MAXPATHL);
  844.     if (setfname(NameBuff, NULL, TRUE) == FAIL)
  845.         goto theend;
  846.     }
  847.  
  848.     home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL);
  849.     smsg((char_u *)"Using swap file \"%s\"", NameBuff);
  850.  
  851.     if (curbuf->b_ffname == NULL)
  852.     STRCPY(NameBuff, "No File");
  853.     else
  854.     home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL);
  855.     smsg((char_u *)"Original file \"%s\"", NameBuff);
  856.     msg_putchar('\n');
  857.  
  858. /*
  859.  * check date of swap file and original file
  860.  */
  861.     mtime = char_to_long(b0p->b0_mtime);
  862.     if (curbuf->b_ffname != NULL &&
  863.         stat((char *)curbuf->b_ffname, &org_stat) != -1 &&
  864.         ((stat((char *)mfp->mf_fname, &swp_stat) != -1 &&
  865.         org_stat.st_mtime > swp_stat.st_mtime) ||
  866.         org_stat.st_mtime != mtime))
  867.     {
  868.     EMSG("Warning: Original file may have been changed");
  869.     }
  870.     out_flush();
  871.     mf_put(mfp, hp, FALSE, FALSE);    /* release block 0 */
  872.     hp = NULL;
  873.  
  874.     /*
  875.      * Now that we are sure that the file is going to be recovered, clear the
  876.      * contents of the current buffer.
  877.      */
  878.     while (!(curbuf->b_ml.ml_flags & ML_EMPTY))
  879.     ml_delete((linenr_t)1, FALSE);
  880.  
  881.     bnum = 1;        /* start with block 1 */
  882.     page_count = 1;    /* which is 1 page */
  883.     lnum = 0;        /* append after line 0 in curbuf */
  884.     line_count = 0;
  885.     idx = 0;        /* start with first index in block 1 */
  886.     error = 0;
  887.     buf->b_ml.ml_stack_top = 0;
  888.     buf->b_ml.ml_stack = NULL;
  889.     buf->b_ml.ml_stack_size = 0;    /* no stack yet */
  890.  
  891.     if (curbuf->b_ffname == NULL)
  892.     cannot_open = TRUE;
  893.     else
  894.     cannot_open = FALSE;
  895.  
  896.     serious_error = FALSE;
  897.     for ( ; !got_int; line_breakcheck())
  898.     {
  899.     if (hp != NULL)
  900.         mf_put(mfp, hp, FALSE, FALSE);    /* release previous block */
  901.  
  902.     /*
  903.      * get block
  904.      */
  905.     if ((hp = mf_get(mfp, (blocknr_t)bnum, page_count)) == NULL)
  906.     {
  907.         if (bnum == 1)
  908.         {
  909.         EMSG2("Unable to read block 1 from %s", mfp->mf_fname);
  910.         goto theend;
  911.         }
  912.         ++error;
  913.         ml_append(lnum++, (char_u *)"???MANY LINES MISSING",
  914.                                 (colnr_t)0, TRUE);
  915.     }
  916.     else        /* there is a block */
  917.     {
  918.         pp = (PTR_BL *)(hp->bh_data);
  919.         if (pp->pb_id == PTR_ID)        /* it is a pointer block */
  920.         {
  921.         /* check line count when using pointer block first time */
  922.         if (idx == 0 && line_count != 0)
  923.         {
  924.             for (i = 0; i < (int)pp->pb_count; ++i)
  925.             line_count -= pp->pb_pointer[i].pe_line_count;
  926.             if (line_count != 0)
  927.             {
  928.             ++error;
  929.             ml_append(lnum++, (char_u *)"???LINE COUNT WRONG",
  930.                                 (colnr_t)0, TRUE);
  931.             }
  932.         }
  933.  
  934.         if (pp->pb_count == 0)
  935.         {
  936.             ml_append(lnum++, (char_u *)"???EMPTY BLOCK",
  937.                                 (colnr_t)0, TRUE);
  938.             ++error;
  939.         }
  940.         else if (idx < (int)pp->pb_count)    /* go a block deeper */
  941.         {
  942.             if (pp->pb_pointer[idx].pe_bnum < 0)
  943.             {
  944.             /*
  945.              * Data block with negative block number.
  946.              * Try to read lines from the original file.
  947.              * This is slow, but it works.
  948.              */
  949.             if (!cannot_open)
  950.             {
  951.                 line_count = pp->pb_pointer[idx].pe_line_count;
  952.                 if (readfile(curbuf->b_ffname, NULL, lnum,
  953.                     pp->pb_pointer[idx].pe_old_lnum - 1,
  954.                     line_count, 0) == FAIL)
  955.                 cannot_open = TRUE;
  956.                 else
  957.                 lnum += line_count;
  958.             }
  959.             if (cannot_open)
  960.             {
  961.                 ++error;
  962.                 ml_append(lnum++, (char_u *)"???LINES MISSING",
  963.                                 (colnr_t)0, TRUE);
  964.             }
  965.             ++idx;        /* get same block again for next index */
  966.             continue;
  967.             }
  968.  
  969.             /*
  970.              * going one block deeper in the tree
  971.              */
  972.             if ((top = ml_add_stack(buf)) < 0)    /* new entry in stack */
  973.             {
  974.             ++error;
  975.             break;            /* out of memory */
  976.             }
  977.             ip = &(buf->b_ml.ml_stack[top]);
  978.             ip->ip_bnum = bnum;
  979.             ip->ip_index = idx;
  980.  
  981.             bnum = pp->pb_pointer[idx].pe_bnum;
  982.             line_count = pp->pb_pointer[idx].pe_line_count;
  983.             page_count = pp->pb_pointer[idx].pe_page_count;
  984.             continue;
  985.         }
  986.         }
  987.         else        /* not a pointer block */
  988.         {
  989.         dp = (DATA_BL *)(hp->bh_data);
  990.         if (dp->db_id != DATA_ID)    /* block id wrong */
  991.         {
  992.             if (bnum == 1)
  993.             {
  994.             EMSG2("Block 1 ID wrong (%s not a .swp file?)",
  995.                                    mfp->mf_fname);
  996.             goto theend;
  997.             }
  998.             ++error;
  999.             ml_append(lnum++, (char_u *)"???BLOCK MISSING",
  1000.                                 (colnr_t)0, TRUE);
  1001.         }
  1002.         else
  1003.         {
  1004.             /*
  1005.              * it is a data block
  1006.              * Append all the lines in this block
  1007.              */
  1008.             has_error = FALSE;
  1009.             /*
  1010.              * check length of block
  1011.              * if wrong, use length in pointer block
  1012.              */
  1013.             if (page_count * mfp->mf_page_size != dp->db_txt_end)
  1014.             {
  1015.             ml_append(lnum++, (char_u *)"??? from here until ???END lines may be messed up",
  1016.                                 (colnr_t)0, TRUE);
  1017.             ++error;
  1018.             has_error = TRUE;
  1019.             dp->db_txt_end = page_count * mfp->mf_page_size;
  1020.             }
  1021.  
  1022.             /* make sure there is a NUL at the end of the block */
  1023.             *((char_u *)dp + dp->db_txt_end - 1) = NUL;
  1024.  
  1025.             /*
  1026.              * check number of lines in block
  1027.              * if wrong, use count in data block
  1028.              */
  1029.             if (line_count != dp->db_line_count)
  1030.             {
  1031.             ml_append(lnum++, (char_u *)"??? from here until ???END lines may have been inserted/deleted",
  1032.                                 (colnr_t)0, TRUE);
  1033.             ++error;
  1034.             has_error = TRUE;
  1035.             }
  1036.  
  1037.             for (i = 0; i < dp->db_line_count; ++i)
  1038.             {
  1039.             txt_start = (dp->db_index[i] & DB_INDEX_MASK);
  1040.             if (txt_start <= HEADER_SIZE ||
  1041.                          txt_start >= (int)dp->db_txt_end)
  1042.             {
  1043.                 p = (char_u *)"???";
  1044.                 ++error;
  1045.             }
  1046.             else
  1047.                 p = (char_u *)dp + txt_start;
  1048.             ml_append(lnum++, p, (colnr_t)0, TRUE);
  1049.             }
  1050.             if (has_error)
  1051.             ml_append(lnum++, (char_u *)"???END", (colnr_t)0, TRUE);
  1052.         }
  1053.         }
  1054.     }
  1055.  
  1056.     if (buf->b_ml.ml_stack_top == 0)    /* finished */
  1057.         break;
  1058.  
  1059.     /*
  1060.      * go one block up in the tree
  1061.      */
  1062.     ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
  1063.     bnum = ip->ip_bnum;
  1064.     idx = ip->ip_index + 1;        /* go to next index */
  1065.     page_count = 1;
  1066.     }
  1067.  
  1068.     /*
  1069.      * The dummy line from the empty buffer will now be after the last line in
  1070.      * the buffer. Delete it.
  1071.      */
  1072.     ml_delete(curbuf->b_ml.ml_line_count, FALSE);
  1073.     curbuf->b_flags |= BF_RECOVERED;
  1074.  
  1075.     recoverymode = FALSE;
  1076.     if (got_int)
  1077.     EMSG("Recovery Interrupted");
  1078.     else if (error)
  1079.     EMSG("Errors detected while recovering; look for lines starting with ???");
  1080.     else
  1081.     {
  1082.     MSG("Recovery completed. You should check if everything is OK.");
  1083.     MSG_PUTS("\n(You might want to write out this file under another name\n");
  1084.     MSG_PUTS("and run diff with the original file to check for changes)\n");
  1085.     MSG_PUTS("Delete the .swp file afterwards.\n\n");
  1086.     cmdline_row = msg_row;
  1087.     }
  1088.  
  1089. theend:
  1090.     if (mfp != NULL)
  1091.     {
  1092.     if (hp != NULL)
  1093.         mf_put(mfp, hp, FALSE, FALSE);
  1094.     mf_close(mfp, FALSE);        /* will also vim_free(mfp->mf_fname) */
  1095.     }
  1096.     vim_free(buf);
  1097.     if (serious_error && called_from_main)
  1098.     ml_close(curbuf, TRUE);
  1099. #ifdef AUTOCMD
  1100.     else
  1101.     apply_autocmds(EVENT_BUFREADPOST, NULL, curbuf->b_fname, FALSE);
  1102. #endif
  1103.     return;
  1104. }
  1105.  
  1106. /*
  1107.  * Find the names of swap files in current directory and the directory given
  1108.  * with the 'directory' option.
  1109.  *
  1110.  * Used to:
  1111.  * - list the swap files for "vim -r"
  1112.  * - count the number of swap files when recovering
  1113.  * - list the swap files when recovering
  1114.  * - find the name of the n'th swap file when recovering
  1115.  */
  1116.     int
  1117. recover_names(fname, list, nr)
  1118.     char_u    **fname;    /* base for swap file name */
  1119.     int        list;        /* when TRUE, list the swap file names */
  1120.     int        nr;        /* when non-zero, return nr'th swap file name */
  1121. {
  1122.     int        num_names;
  1123.     char_u    *(names[6]);
  1124.     char_u    *tail;
  1125.     char_u    *p;
  1126.     int        num_files;
  1127.     int        file_count = 0;
  1128.     char_u    **files;
  1129.     int        i;
  1130.     char_u    *dirp;
  1131.     char_u    *dir_name;
  1132.  
  1133.     if (list)
  1134.     {
  1135.         /* use msg() to start the scrolling properly */
  1136.     msg((char_u *)"Swap files found:");
  1137.     msg_putchar('\n');
  1138.     }
  1139.     expand_interactively = TRUE;
  1140.  
  1141.     /*
  1142.      * Do the loop for every directory in 'directory'.
  1143.      * First allocate some memory to put the directory name in.
  1144.      */
  1145.     dir_name = alloc((unsigned)STRLEN(p_dir) + 1);
  1146.     dirp = p_dir;
  1147.     while (dir_name != NULL && *dirp)
  1148.     {
  1149.     /*
  1150.      * Isolate a directory name from *dirp and put it in dir_name (we know
  1151.      * it is large enough, so use 31000 for length).
  1152.      * Advance dirp to next directory name.
  1153.      */
  1154.     (void)copy_option_part(&dirp, dir_name, 31000, ",");
  1155.  
  1156.     if (dir_name[0] == '.' && dir_name[1] == NUL)    /* check current dir */
  1157.     {
  1158.         if (fname == NULL || *fname == NULL)
  1159.         {
  1160.         names[0] = vim_strsave((char_u *)"*.sw?");
  1161. #ifdef UNIX
  1162.             /* for Unix names starting with a dot are special */
  1163.         names[1] = vim_strsave((char_u *)".*.sw?");
  1164.         names[2] = vim_strsave((char_u *)".sw?");
  1165.         num_names = 3;
  1166. #else
  1167.         num_names = 1;
  1168. #endif
  1169.         }
  1170.         else
  1171.         num_names = recov_file_names(names, *fname, TRUE);
  1172.     }
  1173.     else                /* check directory dir_name */
  1174.     {
  1175.         if (fname == NULL || *fname == NULL)
  1176.         {
  1177.         names[0] = concat_fnames(dir_name, (char_u *)"*.sw?", TRUE);
  1178. #ifdef UNIX
  1179.             /* for Unix names starting with a dot are special */
  1180.         names[1] = concat_fnames(dir_name, (char_u *)".*.sw?", TRUE);
  1181.         names[2] = concat_fnames(dir_name, (char_u *)".sw?", TRUE);
  1182.         num_names = 3;
  1183. #else
  1184.         num_names = 1;
  1185. #endif
  1186.         }
  1187.         else
  1188.         {
  1189.         tail = gettail(*fname);
  1190.         tail = concat_fnames(dir_name, tail, TRUE);
  1191.         if (tail == NULL)
  1192.             num_names = 0;
  1193.         else
  1194.         {
  1195.             num_names = recov_file_names(names, tail, FALSE);
  1196.             vim_free(tail);
  1197.         }
  1198.         }
  1199.     }
  1200.  
  1201.         /* check for out-of-memory */
  1202.     for (i = 0; i < num_names; ++i)
  1203.     {
  1204.         if (names[i] == NULL)
  1205.         {
  1206.         for (i = 0; i < num_names; ++i)
  1207.             vim_free(names[i]);
  1208.         num_names = 0;
  1209.         }
  1210.     }
  1211.     if (num_names == 0)
  1212.         num_files = 0;
  1213.     else if (expand_wildcards(num_names, names, &num_files, &files,
  1214.                                  EW_FILE) == FAIL)
  1215.         num_files = 0;
  1216.  
  1217.     /*
  1218.      * When no swap file found, wildcard expansion might have failed (e.g.
  1219.      * not able to execute the shell).
  1220.      * Try finding a swap file by simply adding ".swp" to the file name.
  1221.      */
  1222.     if (*dirp == NUL && file_count + num_files == 0
  1223.                        && fname != NULL && *fname != NULL)
  1224.     {
  1225.         struct stat        st;
  1226.         char_u        *swapname;
  1227.  
  1228.         swapname = modname(*fname, (char_u *)".swp", TRUE);
  1229.         if (swapname != NULL)
  1230.         {
  1231.         if (stat((char *)swapname, &st) != -1)        /* It exists! */
  1232.         {
  1233.             files = (char_u **)alloc((unsigned)sizeof(char_u *));
  1234.             if (files != NULL)
  1235.             {
  1236.             files[0] = swapname;
  1237.             swapname = NULL;
  1238.             num_files = 1;
  1239.             }
  1240.         }
  1241.         vim_free(swapname);
  1242.         }
  1243.     }
  1244.  
  1245.     /*
  1246.      * remove swapfile name of the current buffer, it must be ignored
  1247.      */
  1248.     if (curbuf->b_ml.ml_mfp != NULL &&
  1249.                 (p = curbuf->b_ml.ml_mfp->mf_fname) != NULL)
  1250.     {
  1251.         for (i = 0; i < num_files; ++i)
  1252.         if (fullpathcmp(p, files[i], TRUE) & FPC_SAME)
  1253.         {
  1254.             vim_free(files[i]);
  1255.             --num_files;
  1256.             for ( ; i < num_files; ++i)
  1257.             files[i] = files[i + 1];
  1258.         }
  1259.     }
  1260.     if (nr)
  1261.     {
  1262.         file_count += num_files;
  1263.         if (nr <= file_count)
  1264.         {
  1265.         *fname = vim_strsave(files[nr - 1 + num_files - file_count]);
  1266.         dirp = (char_u *)"";            /* stop searching */
  1267.         }
  1268.     }
  1269.     else if (list)
  1270.     {
  1271.         if (dir_name[0] == '.' && dir_name[1] == NUL)
  1272.         {
  1273.         if (fname == NULL || *fname == NULL)
  1274.             MSG_PUTS("   In current directory:\n");
  1275.         else
  1276.             MSG_PUTS("   Using specified name:\n");
  1277.         }
  1278.         else
  1279.         {
  1280.         MSG_PUTS("   In directory ");
  1281.         msg_home_replace(dir_name);
  1282.         MSG_PUTS(":\n");
  1283.         }
  1284.  
  1285.         if (num_files)
  1286.         {
  1287.         for (i = 0; i < num_files; ++i)
  1288.         {
  1289.             /* print the swap file name */
  1290.             msg_outnum((long)++file_count);
  1291.             MSG_PUTS(".    ");
  1292.             msg_puts(gettail(files[i]));
  1293.             msg_putchar('\n');
  1294.             swapfile_info(files[i]);
  1295.         }
  1296.         }
  1297.         else
  1298.         MSG_PUTS("      -- none --\n");
  1299.         out_flush();
  1300.     }
  1301.     else
  1302.         file_count += num_files;
  1303.  
  1304.     for (i = 0; i < num_names; ++i)
  1305.         vim_free(names[i]);
  1306.     FreeWild(num_files, files);
  1307.     }
  1308.     vim_free(dir_name);
  1309.     expand_interactively = FALSE;
  1310.     return file_count;
  1311. }
  1312.  
  1313. /*
  1314.  * Give information about an existing swap file
  1315.  */
  1316.     static void
  1317. swapfile_info(fname)
  1318.     char_u    *fname;
  1319. {
  1320.     struct stat        st;
  1321.     int            fd;
  1322.     struct block0   b0;
  1323.     time_t        x;
  1324.  
  1325.     /* print the swap file date */
  1326.     if (stat((char *)fname, &st) != -1)
  1327.     {
  1328.     MSG_PUTS("             dated: ");
  1329.     x = st.st_mtime;            /* Manx C can't do &st.st_mtime */
  1330.     MSG_PUTS(ctime(&x));
  1331.     }
  1332.  
  1333.     /*
  1334.      * print the original file name
  1335.      */
  1336.     fd = open((char *)fname, O_RDONLY | O_EXTRA);
  1337.     if (fd >= 0)
  1338.     {
  1339.     if (read(fd, (char *)&b0, sizeof(b0)) == sizeof(b0))
  1340.     {
  1341.         if (STRNCMP(b0.b0_version, "VIM 3.0", 7) == 0)
  1342.         {
  1343.         MSG_PUTS("         [from Vim version 3.0]");
  1344.         }
  1345.         else if (b0.b0_id[0] != BLOCK0_ID0 ||
  1346.                 b0.b0_id[1] != BLOCK0_ID1)
  1347.         {
  1348.         MSG_PUTS("         [is not a swap file]");
  1349.         }
  1350.         else
  1351.         {
  1352.         MSG_PUTS("         file name: ");
  1353.         msg_outtrans(b0.b0_fname);
  1354.  
  1355.         if (*(b0.b0_hname) != NUL)
  1356.         {
  1357.             MSG_PUTS("\n         host name: ");
  1358.             msg_outtrans(b0.b0_hname);
  1359.         }
  1360.  
  1361.         if (*(b0.b0_uname) != NUL)
  1362.         {
  1363.             MSG_PUTS("\n         user name: ");
  1364.             msg_outtrans(b0.b0_uname);
  1365.         }
  1366.  
  1367.         if (char_to_long(b0.b0_pid) != 0L)
  1368.         {
  1369.             MSG_PUTS("\n        process ID: ");
  1370.             msg_outnum(char_to_long(b0.b0_pid));
  1371. #if defined(UNIX) || defined(__EMX__)
  1372.             /* EMX kill() not working correctly, it seems */
  1373.             if (kill((pid_t)char_to_long(b0.b0_pid), 0) == 0)
  1374.             MSG_PUTS(" (still running)");
  1375. #endif
  1376.         }
  1377.  
  1378.         if (b0_magic_wrong(&b0))
  1379.         {
  1380. #if defined(MSDOS) || defined(WIN32)
  1381.             if (STRNCMP(b0.b0_hname, "PC ", 3) == 0)
  1382.             MSG_PUTS("\n         [not usable with this version of Vim]");
  1383.             else
  1384. #endif
  1385.             MSG_PUTS("\n         [not usable on this computer]");
  1386.         }
  1387.         }
  1388.     }
  1389.     else
  1390.         MSG_PUTS("         [cannot be read]");
  1391.     close(fd);
  1392.     }
  1393.     else
  1394.     MSG_PUTS("         [cannot be opened]");
  1395.     msg_putchar('\n');
  1396. }
  1397.  
  1398.     static int
  1399. recov_file_names(names, path, prepend_dot)
  1400.     char_u    **names;
  1401.     char_u    *path;
  1402.     int        prepend_dot;
  1403. {
  1404.     int        num_names;
  1405.  
  1406. #ifdef SHORT_FNAME
  1407.     /*
  1408.      * (MS-DOS) always short names
  1409.      */
  1410.     names[0] = modname(path, (char_u *)".sw?", FALSE);
  1411.     num_names = 1;
  1412. #else /* !SHORT_FNAME */
  1413.     /*
  1414.      * (WIN32) never short names, but do prepend a dot.
  1415.      * (Not MS-DOS or WIN32) maybe short name, maybe not: Try both.
  1416.      * Only use the short name if it is different.
  1417.      */
  1418.     char_u    *p;
  1419.     int        i;
  1420. # ifndef WIN32
  1421.     int        shortname = curbuf->b_shortname;
  1422.  
  1423.     curbuf->b_shortname = FALSE;
  1424. # endif
  1425.  
  1426.     num_names = 0;
  1427.  
  1428.     /*
  1429.      * May also add the file name with a dot prepended, for swap file in same
  1430.      * dir as original file.
  1431.      */
  1432.     if (prepend_dot)
  1433.     {
  1434.     names[num_names] = modname(path, (char_u *)".sw?", TRUE);
  1435.     if (names[num_names] == NULL)
  1436.         goto end;
  1437.     ++num_names;
  1438.     }
  1439.  
  1440.     /*
  1441.      * Form the normal swap file name pattern by appending ".sw?".
  1442.      */
  1443.     names[num_names] = concat_fnames(path, (char_u *)".sw?", FALSE);
  1444.     if (names[num_names] == NULL)
  1445.     goto end;
  1446.     if (num_names >= 1)        /* check if we have the same name twice */
  1447.     {
  1448.     p = names[num_names - 1];
  1449.     i = STRLEN(names[num_names - 1]) - STRLEN(names[num_names]);
  1450.     if (i > 0)
  1451.         p += i;        /* file name has been expanded to full path */
  1452.  
  1453.     if (STRCMP(p, names[num_names]) != 0)
  1454.         ++num_names;
  1455.     else
  1456.         vim_free(names[num_names]);
  1457.     }
  1458.     else
  1459.     ++num_names;
  1460.  
  1461. # ifndef WIN32
  1462.     /*
  1463.      * Also try with 'shortname' set, in case the file is on a DOS filesystem.
  1464.      */
  1465.     curbuf->b_shortname = TRUE;
  1466.     names[num_names] = modname(path, (char_u *)".sw?", FALSE);
  1467.     if (names[num_names] == NULL)
  1468.     goto end;
  1469.  
  1470.     /*
  1471.      * Remove the one from 'shortname', if it's the same as with 'noshortname'.
  1472.      */
  1473.     p = names[num_names];
  1474.     i = STRLEN(names[num_names]) - STRLEN(names[num_names - 1]);
  1475.     if (i > 0)
  1476.     p += i;        /* file name has been expanded to full path */
  1477.     if (STRCMP(names[num_names - 1], p) == 0)
  1478.     vim_free(names[num_names]);
  1479.     else
  1480.     ++num_names;
  1481. # endif
  1482.  
  1483. end:
  1484. # ifndef WIN32
  1485.     curbuf->b_shortname = shortname;
  1486. # endif
  1487.  
  1488. #endif /* !SHORT_FNAME */
  1489.  
  1490.     return num_names;
  1491. }
  1492.  
  1493. /*
  1494.  * sync all memlines
  1495.  *
  1496.  * If 'check_file' is TRUE, check if original file exists and was not changed.
  1497.  * If 'check_char' is TRUE, stop syncing when character becomes available, but
  1498.  * always sync at least one block.
  1499.  */
  1500.     void
  1501. ml_sync_all(check_file, check_char)
  1502.     int        check_file;
  1503.     int        check_char;
  1504. {
  1505.     BUF            *buf;
  1506.     struct stat        st;
  1507.  
  1508.     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  1509.     {
  1510.     if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
  1511.         continue;                /* no file */
  1512.  
  1513.     ml_flush_line(buf);            /* flush buffered line */
  1514.                         /* flush locked block */
  1515.     (void)ml_find_line(buf, (linenr_t)0, ML_FLUSH);
  1516.     if (buf_changed(buf) && check_file && mf_need_trans(buf->b_ml.ml_mfp)
  1517.                              && buf->b_ffname != NULL)
  1518.     {
  1519.         /*
  1520.          * if original file does not exist anymore or has been changed
  1521.          * call ml_preserve to get rid of all negative numbered blocks
  1522.          */
  1523.         if (stat((char *)buf->b_ffname, &st) == -1 ||
  1524.                 st.st_mtime != buf->b_mtime_read)
  1525.         {
  1526.         ml_preserve(buf, FALSE);
  1527.         need_check_timestamps = TRUE;    /* give message later */
  1528.         }
  1529.     }
  1530.     if (buf->b_ml.ml_mfp->mf_dirty)
  1531.     {
  1532.         (void)mf_sync(buf->b_ml.ml_mfp, (check_char ? MFS_STOP : 0)
  1533.                     | (buf_changed(buf) ? MFS_FLUSH : 0));
  1534.         if (check_char && ui_char_avail())    /* character available now */
  1535.         break;
  1536.     }
  1537.     }
  1538. }
  1539.  
  1540. /*
  1541.  * sync one buffer, including negative blocks
  1542.  *
  1543.  * after this all the blocks are in the swap file
  1544.  *
  1545.  * Used for the :preserve command and when the original file has been
  1546.  * changed or deleted.
  1547.  *
  1548.  * when message is TRUE the success of preserving is reported
  1549.  */
  1550.     void
  1551. ml_preserve(buf, message)
  1552.     BUF        *buf;
  1553.     int        message;
  1554. {
  1555.     BHDR    *hp;
  1556.     linenr_t    lnum;
  1557.     MEMFILE    *mfp = buf->b_ml.ml_mfp;
  1558.     int        status;
  1559.  
  1560.     if (mfp == NULL || mfp->mf_fname == NULL)
  1561.     {
  1562.     if (message)
  1563.         EMSG("Cannot preserve, there is no swap file");
  1564.     return;
  1565.     }
  1566.  
  1567.     ml_flush_line(buf);                    /* flush buffered line */
  1568.     (void)ml_find_line(buf, (linenr_t)0, ML_FLUSH); /* flush locked block */
  1569.     status = mf_sync(mfp, MFS_ALL | MFS_FLUSH);
  1570.  
  1571.     /* stack is invalid after mf_sync(.., MFS_ALL) */
  1572.     buf->b_ml.ml_stack_top = 0;
  1573.  
  1574.     /*
  1575.      * Some of the data blocks may have been changed from negative to
  1576.      * positive block number. In that case the pointer blocks need to be
  1577.      * updated.
  1578.      *
  1579.      * We don't know in which pointer block the references are, so we visit
  1580.      * all data blocks until there are no more translations to be done (or
  1581.      * we hit the end of the file, which can only happen in case a write fails,
  1582.      * e.g. when file system if full).
  1583.      * ml_find_line() does the work by translating the negative block numbers
  1584.      * when getting the first line of each data block.
  1585.      */
  1586.     if (mf_need_trans(mfp))
  1587.     {
  1588.     lnum = 1;
  1589.     while (mf_need_trans(mfp) && lnum <= buf->b_ml.ml_line_count)
  1590.     {
  1591.         hp = ml_find_line(buf, lnum, ML_FIND);
  1592.         if (hp == NULL)
  1593.         {
  1594.         status = FAIL;
  1595.         goto theend;
  1596.         }
  1597.         CHECK(buf->b_ml.ml_locked_low != lnum, "low != lnum");
  1598.         lnum = buf->b_ml.ml_locked_high + 1;
  1599.     }
  1600.     (void)ml_find_line(buf, (linenr_t)0, ML_FLUSH);    /* flush locked block */
  1601.     /* sync the updated pointer blocks */
  1602.     if (mf_sync(mfp, MFS_ALL | MFS_FLUSH) == FAIL)
  1603.         status = FAIL;
  1604.     buf->b_ml.ml_stack_top = 0;        /* stack is invalid now */
  1605.     }
  1606. theend:
  1607.     if (message)
  1608.     {
  1609.     if (status == OK)
  1610.         MSG("File preserved");
  1611.     else
  1612.         EMSG("Preserve failed");
  1613.     }
  1614. }
  1615.  
  1616. /*
  1617.  * get a pointer to a (read-only copy of a) line
  1618.  *
  1619.  * On failure an error message is given and IObuff is returned (to avoid
  1620.  * having to check for error everywhere).
  1621.  */
  1622.     char_u  *
  1623. ml_get(lnum)
  1624.     linenr_t    lnum;
  1625. {
  1626.     return ml_get_buf(curbuf, lnum, FALSE);
  1627. }
  1628.  
  1629. /*
  1630.  * ml_get_pos: get pointer to position 'pos'
  1631.  */
  1632.     char_u *
  1633. ml_get_pos(pos)
  1634.     FPOS    *pos;
  1635. {
  1636.     return (ml_get_buf(curbuf, pos->lnum, FALSE) + pos->col);
  1637. }
  1638.  
  1639. /*
  1640.  * ml_get_curline: get pointer to cursor line.
  1641.  */
  1642.     char_u *
  1643. ml_get_curline()
  1644. {
  1645.     return ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE);
  1646. }
  1647.  
  1648. /*
  1649.  * ml_get_cursor: get pointer to cursor position
  1650.  */
  1651.     char_u *
  1652. ml_get_cursor()
  1653. {
  1654.     return (ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE) +
  1655.                             curwin->w_cursor.col);
  1656. }
  1657.  
  1658. /*
  1659.  * get a pointer to a line in a specific buffer
  1660.  *
  1661.  *  will_change: if TRUE mark the buffer dirty (chars in the line will be
  1662.  *  changed)
  1663.  */
  1664.     char_u  *
  1665. ml_get_buf(buf, lnum, will_change)
  1666.     BUF        *buf;
  1667.     linenr_t    lnum;
  1668.     int        will_change;        /* line will be changed */
  1669. {
  1670.     BHDR    *hp;
  1671.     DATA_BL *dp;
  1672.     char_u  *ptr;
  1673.  
  1674.     if (lnum > buf->b_ml.ml_line_count)    /* invalid line number */
  1675.     {
  1676.     EMSGN("ml_get: invalid lnum: %ld", lnum);
  1677. errorret:
  1678.     STRCPY(IObuff, "???");
  1679.     return IObuff;
  1680.     }
  1681.     if (lnum <= 0)            /* pretend line 0 is line 1 */
  1682.     lnum = 1;
  1683.  
  1684.     if (buf->b_ml.ml_mfp == NULL)    /* there are no lines */
  1685.     return (char_u *)"";
  1686.  
  1687. /*
  1688.  * See if it is the same line as requested last time.
  1689.  * Otherwise may need to flush last used line.
  1690.  */
  1691.     if (buf->b_ml.ml_line_lnum != lnum)
  1692.     {
  1693.     ml_flush_line(buf);
  1694.  
  1695.     /*
  1696.      * Find the data block containing the line.
  1697.      * This also fills the stack with the blocks from the root to the data
  1698.      * block and releases any locked block.
  1699.      */
  1700.     if ((hp = ml_find_line(buf, lnum, ML_FIND)) == NULL)
  1701.     {
  1702.         EMSGN("ml_get: cannot find line %ld", lnum);
  1703.         goto errorret;
  1704.     }
  1705.  
  1706.     dp = (DATA_BL *)(hp->bh_data);
  1707.  
  1708.     ptr = (char_u *)dp + ((dp->db_index[lnum - buf->b_ml.ml_locked_low]) & DB_INDEX_MASK);
  1709.     buf->b_ml.ml_line_ptr = ptr;
  1710.     buf->b_ml.ml_line_lnum = lnum;
  1711.     buf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
  1712.     }
  1713.     if (will_change)
  1714.     {
  1715.     buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
  1716. #ifdef SYNTAX_HL
  1717.     if (buf->b_syn_change_lnum > lnum)
  1718.         buf->b_syn_change_lnum = lnum;
  1719. #endif
  1720.     }
  1721.  
  1722.     return buf->b_ml.ml_line_ptr;
  1723. }
  1724.  
  1725. /*
  1726.  * Check if a line that was just obtained by a call to ml_get
  1727.  * is in allocated memory.
  1728.  */
  1729.     int
  1730. ml_line_alloced()
  1731. {
  1732.     return (curbuf->b_ml.ml_flags & ML_LINE_DIRTY);
  1733. }
  1734.  
  1735. /*
  1736.  * append a line after lnum (may be 0 to insert a line in front of the file)
  1737.  *
  1738.  *   newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum
  1739.  *        will be set for recovery
  1740.  *
  1741.  * return FAIL for failure, OK otherwise
  1742.  */
  1743.     int
  1744. ml_append(lnum, line, len, newfile)
  1745.     linenr_t    lnum;        /* append after this line (can be 0) */
  1746.     char_u    *line;        /* text of the new line */
  1747.     colnr_t    len;        /* length of new line, including NUL, or 0 */
  1748.     int        newfile;    /* flag, see above */
  1749. {
  1750. #ifdef SYNTAX_HL
  1751.     if (curbuf->b_syn_change_lnum > lnum + 1)
  1752.     curbuf->b_syn_change_lnum = lnum + 1;
  1753. #endif
  1754.  
  1755.     if (curbuf->b_ml.ml_line_lnum != 0)
  1756.     ml_flush_line(curbuf);
  1757.     return ml_append_int(curbuf, lnum, line, len, newfile, FALSE);
  1758. }
  1759.  
  1760.     static int
  1761. ml_append_int(buf, lnum, line, len, newfile, mark)
  1762.     BUF        *buf;
  1763.     linenr_t    lnum;        /* append after this line (can be 0) */
  1764.     char_u    *line;        /* text of the new line */
  1765.     colnr_t    len;        /* length of line, including NUL, or 0 */
  1766.     int        newfile;    /* flag, see above */
  1767.     int        mark;        /* mark the new line */
  1768. {
  1769.     int        i;
  1770.     int        line_count;    /* number of indexes in current block */
  1771.     int        offset;
  1772.     int        from, to;
  1773.     int        space_needed;    /* space needed for new line */
  1774.     int        page_size;
  1775.     int        page_count;
  1776.     int        db_idx;        /* index for lnum in data block */
  1777.     BHDR    *hp;
  1778.     MEMFILE    *mfp;
  1779.     DATA_BL    *dp;
  1780.     PTR_BL    *pp;
  1781.     IPTR    *ip;
  1782.  
  1783.                     /* lnum out of range */
  1784.     if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL)
  1785.     return FAIL;
  1786.  
  1787.     if (lowest_marked && lowest_marked > lnum)
  1788.     lowest_marked = lnum + 1;
  1789.  
  1790.     if (len == 0)
  1791.     len = STRLEN(line) + 1;        /* space needed for the text */
  1792.     space_needed = len + INDEX_SIZE;    /* space needed for text + index */
  1793.  
  1794.     mfp = buf->b_ml.ml_mfp;
  1795.     page_size = mfp->mf_page_size;
  1796.  
  1797. /*
  1798.  * find the data block containing the previous line
  1799.  * This also fills the stack with the blocks from the root to the data block
  1800.  * This also releases any locked block.
  1801.  */
  1802.     if ((hp = ml_find_line(buf, lnum == 0 ? (linenr_t)1 : lnum,
  1803.                               ML_INSERT)) == NULL)
  1804.     return FAIL;
  1805.  
  1806.     buf->b_ml.ml_flags &= ~ML_EMPTY;
  1807.  
  1808.     if (lnum == 0)        /* got line one instead, correct db_idx */
  1809.     db_idx = -1;        /* careful, it is negative! */
  1810.     else
  1811.     db_idx = lnum - buf->b_ml.ml_locked_low;
  1812.         /* get line count before the insertion */
  1813.     line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
  1814.  
  1815.     dp = (DATA_BL *)(hp->bh_data);
  1816.  
  1817. /*
  1818.  * If
  1819.  * - there is not enough room in the current block
  1820.  * - appending to the last line in the block
  1821.  * - not appending to the last line in the file
  1822.  * insert in front of the next block.
  1823.  */
  1824.     if ((int)dp->db_free < space_needed && db_idx == line_count - 1
  1825.                         && lnum < buf->b_ml.ml_line_count)
  1826.     {
  1827.     /*
  1828.      * Now that the line is not going to be inserted in the block that we
  1829.      * expected, the line count has to be adjusted in the pointer blocks
  1830.      * by using ml_locked_lineadd.
  1831.      */
  1832.     --(buf->b_ml.ml_locked_lineadd);
  1833.     --(buf->b_ml.ml_locked_high);
  1834.     if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL)
  1835.         return FAIL;
  1836.  
  1837.     db_idx = -1;            /* careful, it is negative! */
  1838.             /* get line count before the insertion */
  1839.     line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
  1840.     CHECK(buf->b_ml.ml_locked_low != lnum + 1, "locked_low != lnum + 1");
  1841.  
  1842.     dp = (DATA_BL *)(hp->bh_data);
  1843.     }
  1844.  
  1845.     ++buf->b_ml.ml_line_count;
  1846.  
  1847.     if ((int)dp->db_free >= space_needed)    /* enough room in data block */
  1848.     {
  1849. /*
  1850.  * Insert new line in existing data block, or in data block allocated above.
  1851.  */
  1852.     dp->db_txt_start -= len;
  1853.     dp->db_free -= space_needed;
  1854.     ++(dp->db_line_count);
  1855.  
  1856.     /*
  1857.      * move the text of the lines that follow to the front
  1858.      * adjust the indexes of the lines that follow
  1859.      */
  1860.     if (line_count > db_idx + 1)        /* if there are following lines */
  1861.     {
  1862.         /*
  1863.          * Offset is the start of the previous line.
  1864.          * This will become the character just after the new line.
  1865.          */
  1866.         if (db_idx < 0)
  1867.         offset = dp->db_txt_end;
  1868.         else
  1869.         offset = ((dp->db_index[db_idx]) & DB_INDEX_MASK);
  1870.         vim_memmove((char *)dp + dp->db_txt_start,
  1871.                       (char *)dp + dp->db_txt_start + len,
  1872.                  (size_t)(offset - (dp->db_txt_start + len)));
  1873.         for (i = line_count - 1; i > db_idx; --i)
  1874.         dp->db_index[i + 1] = dp->db_index[i] - len;
  1875.         dp->db_index[db_idx + 1] = offset - len;
  1876.     }
  1877.     else                    /* add line at the end */
  1878.         dp->db_index[db_idx + 1] = dp->db_txt_start;
  1879.  
  1880.     /*
  1881.      * copy the text into the block
  1882.      */
  1883.     vim_memmove((char *)dp + dp->db_index[db_idx + 1], line, (size_t)len);
  1884.     if (mark)
  1885.         dp->db_index[db_idx + 1] |= DB_MARKED;
  1886.  
  1887.     /*
  1888.      * Mark the block dirty.
  1889.      */
  1890.     buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
  1891.     if (!newfile)
  1892.         buf->b_ml.ml_flags |= ML_LOCKED_POS;
  1893.     }
  1894.     else        /* not enough space in data block */
  1895.     {
  1896. /*
  1897.  * If there is not enough room we have to create a new data block and copy some
  1898.  * lines into it.
  1899.  * Then we have to insert an entry in the pointer block.
  1900.  * If this pointer block also is full, we go up another block, and so on, up
  1901.  * to the root if necessary.
  1902.  * The line counts in the pointer blocks have already been adjusted by
  1903.  * ml_find_line().
  1904.  */
  1905.     long        line_count_left, line_count_right;
  1906.     int        page_count_left, page_count_right;
  1907.     BHDR        *hp_left;
  1908.     BHDR        *hp_right;
  1909.     BHDR        *hp_new;
  1910.     int        lines_moved;
  1911.     int        data_moved = 0;        /* init to shut up gcc */
  1912.     int        total_moved = 0;        /* init to shut up gcc */
  1913.     DATA_BL        *dp_right, *dp_left;
  1914.     int        stack_idx;
  1915.     int        in_left;
  1916.     int        lineadd;
  1917.     blocknr_t   bnum_left, bnum_right;
  1918.     linenr_t    lnum_left, lnum_right;
  1919.     int        pb_idx;
  1920.     PTR_BL        *pp_new;
  1921.  
  1922.     /*
  1923.      * We are going to allocate a new data block. Depending on the
  1924.      * situation it will be put to the left or right of the existing
  1925.      * block.  If possible we put the new line in the left block and move
  1926.      * the lines after it to the right block. Otherwise the new line is
  1927.      * also put in the right block. This method is more efficient when
  1928.      * inserting a lot of lines at one place.
  1929.      */
  1930.     if (db_idx < 0)        /* left block is new, right block is existing */
  1931.     {
  1932.         lines_moved = 0;
  1933.         in_left = TRUE;
  1934.         /* space_needed does not change */
  1935.     }
  1936.     else            /* left block is existing, right block is new */
  1937.     {
  1938.         lines_moved = line_count - db_idx - 1;
  1939.         if (lines_moved == 0)
  1940.         in_left = FALSE;    /* put new line in right block */
  1941.                     /* space_needed does not change */
  1942.         else
  1943.         {
  1944.         data_moved = ((dp->db_index[db_idx]) & DB_INDEX_MASK) -
  1945.                                 dp->db_txt_start;
  1946.         total_moved = data_moved + lines_moved * INDEX_SIZE;
  1947.         if ((int)dp->db_free + total_moved >= space_needed)
  1948.         {
  1949.             in_left = TRUE;    /* put new line in left block */
  1950.             space_needed = total_moved;
  1951.         }
  1952.         else
  1953.         {
  1954.             in_left = FALSE;        /* put new line in right block */
  1955.             space_needed += total_moved;
  1956.         }
  1957.         }
  1958.     }
  1959.  
  1960.     page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size;
  1961.     if ((hp_new = ml_new_data(mfp, newfile, page_count)) == NULL)
  1962.     {
  1963.             /* correct line counts in pointer blocks */
  1964.         --(buf->b_ml.ml_locked_lineadd);
  1965.         --(buf->b_ml.ml_locked_high);
  1966.         return FAIL;
  1967.     }
  1968.     if (db_idx < 0)        /* left block is new */
  1969.     {
  1970.         hp_left = hp_new;
  1971.         hp_right = hp;
  1972.         line_count_left = 0;
  1973.         line_count_right = line_count;
  1974.     }
  1975.     else            /* right block is new */
  1976.     {
  1977.         hp_left = hp;
  1978.         hp_right = hp_new;
  1979.         line_count_left = line_count;
  1980.         line_count_right = 0;
  1981.     }
  1982.     dp_right = (DATA_BL *)(hp_right->bh_data);
  1983.     dp_left = (DATA_BL *)(hp_left->bh_data);
  1984.     bnum_left = hp_left->bh_bnum;
  1985.     bnum_right = hp_right->bh_bnum;
  1986.     page_count_left = hp_left->bh_page_count;
  1987.     page_count_right = hp_right->bh_page_count;
  1988.  
  1989.     /*
  1990.      * May move the new line into the right/new block.
  1991.      */
  1992.     if (!in_left)
  1993.     {
  1994.         dp_right->db_txt_start -= len;
  1995.         dp_right->db_free -= len + INDEX_SIZE;
  1996.         dp_right->db_index[0] = dp_right->db_txt_start;
  1997.         if (mark)
  1998.         dp_right->db_index[0] |= DB_MARKED;
  1999.  
  2000.         vim_memmove((char *)dp_right + dp_right->db_txt_start,
  2001.                                line, (size_t)len);
  2002.         ++line_count_right;
  2003.     }
  2004.     /*
  2005.      * may move lines from the left/old block to the right/new one.
  2006.      */
  2007.     if (lines_moved)
  2008.     {
  2009.         /*
  2010.          */
  2011.         dp_right->db_txt_start -= data_moved;
  2012.         dp_right->db_free -= total_moved;
  2013.         vim_memmove((char *)dp_right + dp_right->db_txt_start,
  2014.             (char *)dp_left + dp_left->db_txt_start,
  2015.             (size_t)data_moved);
  2016.         offset = dp_right->db_txt_start - dp_left->db_txt_start;
  2017.         dp_left->db_txt_start += data_moved;
  2018.         dp_left->db_free += total_moved;
  2019.  
  2020.         /*
  2021.          * update indexes in the new block
  2022.          */
  2023.         for (to = line_count_right, from = db_idx + 1;
  2024.                      from < line_count_left; ++from, ++to)
  2025.         dp_right->db_index[to] = dp->db_index[from] + offset;
  2026.         line_count_right += lines_moved;
  2027.         line_count_left -= lines_moved;
  2028.     }
  2029.  
  2030.     /*
  2031.      * May move the new line into the left (old or new) block.
  2032.      */
  2033.     if (in_left)
  2034.     {
  2035.         dp_left->db_txt_start -= len;
  2036.         dp_left->db_free -= len + INDEX_SIZE;
  2037.         dp_left->db_index[line_count_left] = dp_left->db_txt_start;
  2038.         if (mark)
  2039.         dp_left->db_index[line_count_left] |= DB_MARKED;
  2040.         vim_memmove((char *)dp_left + dp_left->db_txt_start,
  2041.                                line, (size_t)len);
  2042.         ++line_count_left;
  2043.     }
  2044.  
  2045.     if (db_idx < 0)        /* left block is new */
  2046.     {
  2047.         lnum_left = lnum + 1;
  2048.         lnum_right = 0;
  2049.     }
  2050.     else            /* right block is new */
  2051.     {
  2052.         lnum_left = 0;
  2053.         if (in_left)
  2054.         lnum_right = lnum + 2;
  2055.         else
  2056.         lnum_right = lnum + 1;
  2057.     }
  2058.     dp_left->db_line_count = line_count_left;
  2059.     dp_right->db_line_count = line_count_right;
  2060.  
  2061.     /*
  2062.      * release the two data blocks
  2063.      * The new one (hp_new) already has a correct blocknumber.
  2064.      * The old one (hp, in ml_locked) gets a positive blocknumber if
  2065.      * we changed it and we are not editing a new file.
  2066.      */
  2067.     if (lines_moved || in_left)
  2068.         buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
  2069.     if (!newfile && db_idx >= 0 && in_left)
  2070.         buf->b_ml.ml_flags |= ML_LOCKED_POS;
  2071.     mf_put(mfp, hp_new, TRUE, FALSE);
  2072.  
  2073.     /*
  2074.      * flush the old data block
  2075.      * set ml_locked_lineadd to 0, because the updating of the
  2076.      * pointer blocks is done below
  2077.      */
  2078.     lineadd = buf->b_ml.ml_locked_lineadd;
  2079.     buf->b_ml.ml_locked_lineadd = 0;
  2080.     ml_find_line(buf, (linenr_t)0, ML_FLUSH);   /* flush data block */
  2081.  
  2082.     /*
  2083.      * update pointer blocks for the new data block
  2084.      */
  2085.     for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0;
  2086.                                   --stack_idx)
  2087.     {
  2088.         ip = &(buf->b_ml.ml_stack[stack_idx]);
  2089.         pb_idx = ip->ip_index;
  2090.         if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
  2091.         return FAIL;
  2092.         pp = (PTR_BL *)(hp->bh_data);   /* must be pointer block */
  2093.         if (pp->pb_id != PTR_ID)
  2094.         {
  2095.         EMSG("pointer block id wrong 3");
  2096.         mf_put(mfp, hp, FALSE, FALSE);
  2097.         return FAIL;
  2098.         }
  2099.         /*
  2100.          * TODO: If the pointer block is full and we are adding at the end
  2101.          * try to insert in front of the next block
  2102.          */
  2103.         if (pp->pb_count < pp->pb_count_max)    /* block not full, add one entry */
  2104.         {
  2105.         if (pb_idx + 1 < (int)pp->pb_count)
  2106.             vim_memmove(&pp->pb_pointer[pb_idx + 2],
  2107.                 &pp->pb_pointer[pb_idx + 1],
  2108.             (size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN));
  2109.         ++pp->pb_count;
  2110.         pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
  2111.         pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
  2112.         pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
  2113.         pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
  2114.         pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
  2115.         pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
  2116.  
  2117.         if (lnum_left != 0)
  2118.             pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
  2119.         if (lnum_right != 0)
  2120.             pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
  2121.  
  2122.         mf_put(mfp, hp, TRUE, FALSE);
  2123.         buf->b_ml.ml_stack_top = stack_idx + 1;        /* truncate stack */
  2124.  
  2125.         if (lineadd)
  2126.         {
  2127.             --(buf->b_ml.ml_stack_top);
  2128.             /* fix line count for rest of blocks in the stack */
  2129.             ml_lineadd(buf, lineadd);
  2130.                             /* fix stack itself */
  2131.             buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
  2132.                                       lineadd;
  2133.             ++(buf->b_ml.ml_stack_top);
  2134.         }
  2135.  
  2136.         return OK;
  2137.         }
  2138.         else            /* pointer block full */
  2139.         {
  2140.         /*
  2141.          * split the pointer block
  2142.          * allocate a new pointer block
  2143.          * move some of the pointer into the new block
  2144.          * prepare for updating the parent block
  2145.          */
  2146.         for (;;)    /* do this twice when splitting block 1 */
  2147.         {
  2148.             hp_new = ml_new_ptr(mfp);
  2149.             if (hp_new == NULL)        /* TODO: try to fix tree */
  2150.             return FAIL;
  2151.             pp_new = (PTR_BL *)(hp_new->bh_data);
  2152.  
  2153.             if (hp->bh_bnum != 1)
  2154.             break;
  2155.  
  2156.             /*
  2157.              * if block 1 becomes full the tree is given an extra level
  2158.              * The pointers from block 1 are moved into the new block.
  2159.              * block 1 is updated to point to the new block
  2160.              * then continue to split the new block
  2161.              */
  2162.             vim_memmove(pp_new, pp, (size_t)page_size);
  2163.             pp->pb_count = 1;
  2164.             pp->pb_pointer[0].pe_bnum = hp_new->bh_bnum;
  2165.             pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count;
  2166.             pp->pb_pointer[0].pe_old_lnum = 1;
  2167.             pp->pb_pointer[0].pe_page_count = 1;
  2168.             mf_put(mfp, hp, TRUE, FALSE);   /* release block 1 */
  2169.             hp = hp_new;            /* new block is to be split */
  2170.             pp = pp_new;
  2171.             CHECK(stack_idx != 0, "stack_idx should be 0");
  2172.             ip->ip_index = 0;
  2173.             ++stack_idx;    /* do block 1 again later */
  2174.         }
  2175.         /*
  2176.          * move the pointers after the current one to the new block
  2177.          * If there are none, the new entry will be in the new block.
  2178.          */
  2179.         total_moved = pp->pb_count - pb_idx - 1;
  2180.         if (total_moved)
  2181.         {
  2182.             vim_memmove(&pp_new->pb_pointer[0],
  2183.                 &pp->pb_pointer[pb_idx + 1],
  2184.                 (size_t)(total_moved) * sizeof(PTR_EN));
  2185.             pp_new->pb_count = total_moved;
  2186.             pp->pb_count -= total_moved - 1;
  2187.             pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
  2188.             pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
  2189.             pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
  2190.             if (lnum_right)
  2191.             pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
  2192.         }
  2193.         else
  2194.         {
  2195.             pp_new->pb_count = 1;
  2196.             pp_new->pb_pointer[0].pe_bnum = bnum_right;
  2197.             pp_new->pb_pointer[0].pe_line_count = line_count_right;
  2198.             pp_new->pb_pointer[0].pe_page_count = page_count_right;
  2199.             pp_new->pb_pointer[0].pe_old_lnum = lnum_right;
  2200.         }
  2201.         pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
  2202.         pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
  2203.         pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
  2204.         if (lnum_left)
  2205.             pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
  2206.         lnum_left = 0;
  2207.         lnum_right = 0;
  2208.  
  2209.         /*
  2210.          * recompute line counts
  2211.          */
  2212.         line_count_right = 0;
  2213.         for (i = 0; i < (int)pp_new->pb_count; ++i)
  2214.             line_count_right += pp_new->pb_pointer[i].pe_line_count;
  2215.         line_count_left = 0;
  2216.         for (i = 0; i < (int)pp->pb_count; ++i)
  2217.             line_count_left += pp->pb_pointer[i].pe_line_count;
  2218.  
  2219.         bnum_left = hp->bh_bnum;
  2220.         bnum_right = hp_new->bh_bnum;
  2221.         page_count_left = 1;
  2222.         page_count_right = 1;
  2223.         mf_put(mfp, hp, TRUE, FALSE);
  2224.         mf_put(mfp, hp_new, TRUE, FALSE);
  2225.         }
  2226.     }
  2227.     EMSG("Updated too many blocks?");
  2228.     buf->b_ml.ml_stack_top = 0;    /* invalidate stack */
  2229.     }
  2230.     return OK;
  2231. }
  2232.  
  2233. /*
  2234.  * replace line lnum, with buffering, in current buffer
  2235.  *
  2236.  * If copy is TRUE, make a copy of the line, otherwise the line has been
  2237.  * copied to allocated memory already.
  2238.  *
  2239.  * return FAIL for failure, OK otherwise
  2240.  */
  2241.     int
  2242. ml_replace(lnum, line, copy)
  2243.     linenr_t    lnum;
  2244.     char_u    *line;
  2245.     int        copy;
  2246. {
  2247.     if (line == NULL)        /* just checking... */
  2248.     return FAIL;
  2249.  
  2250.     if (curbuf->b_ml.ml_line_lnum != lnum)        /* other line buffered */
  2251.     ml_flush_line(curbuf);                /* flush it */
  2252.     else if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) /* same line allocated */
  2253.     vim_free(curbuf->b_ml.ml_line_ptr);        /* free it */
  2254.     if (copy && (line = vim_strsave(line)) == NULL) /* allocate memory */
  2255.     return FAIL;
  2256.     curbuf->b_ml.ml_line_ptr = line;
  2257.     curbuf->b_ml.ml_line_lnum = lnum;
  2258.     curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;
  2259.  
  2260.     return OK;
  2261. }
  2262.  
  2263. /*
  2264.  * delete line 'lnum'
  2265.  *
  2266.  * return FAIL for failure, OK otherwise
  2267.  */
  2268.     int
  2269. ml_delete(lnum, message)
  2270.     linenr_t    lnum;
  2271.     int        message;
  2272. {
  2273. #ifdef SYNTAX_HL
  2274.     if (curbuf->b_syn_change_lnum > lnum)
  2275.     curbuf->b_syn_change_lnum = lnum;
  2276. #endif
  2277.  
  2278.     ml_flush_line(curbuf);
  2279.     return ml_delete_int(curbuf, lnum, message);
  2280. }
  2281.  
  2282.     static int
  2283. ml_delete_int(buf, lnum, message)
  2284.     BUF        *buf;
  2285.     linenr_t    lnum;
  2286.     int        message;
  2287. {
  2288.     BHDR    *hp;
  2289.     MEMFILE *mfp;
  2290.     DATA_BL *dp;
  2291.     PTR_BL  *pp;
  2292.     IPTR    *ip;
  2293.     int        count;        /* number of entries in block */
  2294.     int        idx;
  2295.     int        stack_idx;
  2296.     int        text_start;
  2297.     int        line_start;
  2298.     int        line_size;
  2299.     int        i;
  2300.  
  2301.     if (lnum < 1 || lnum > buf->b_ml.ml_line_count)
  2302.     return FAIL;
  2303.  
  2304.     if (lowest_marked && lowest_marked > lnum)
  2305.     lowest_marked--;
  2306.  
  2307. /*
  2308.  * If the file becomes empty the last line is replaced by an empty line.
  2309.  */
  2310.     if (buf->b_ml.ml_line_count == 1)        /* file becomes empty */
  2311.     {
  2312.     if (message)
  2313.     {
  2314.         keep_msg = no_lines_msg;
  2315.         keep_msg_attr = 0;
  2316.     }
  2317.     i = ml_replace((linenr_t)1, (char_u *)"", TRUE);
  2318.     buf->b_ml.ml_flags |= ML_EMPTY;
  2319.     return i;
  2320.     }
  2321.  
  2322. /*
  2323.  * find the data block containing the line
  2324.  * This also fills the stack with the blocks from the root to the data block
  2325.  * This also releases any locked block.
  2326.  */
  2327.     mfp = buf->b_ml.ml_mfp;
  2328.     if (mfp == NULL)
  2329.     return FAIL;
  2330.  
  2331.     if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL)
  2332.     return FAIL;
  2333.  
  2334.     dp = (DATA_BL *)(hp->bh_data);
  2335.         /* compute line count before the delete */
  2336.     count = (long)(buf->b_ml.ml_locked_high) - (long)(buf->b_ml.ml_locked_low) + 2;
  2337.     idx = lnum - buf->b_ml.ml_locked_low;
  2338.  
  2339.     --buf->b_ml.ml_line_count;
  2340.  
  2341. /*
  2342.  * special case: If there is only one line in the data block it becomes empty.
  2343.  * Then we have to remove the entry, pointing to this data block, from the
  2344.  * pointer block. If this pointer block also becomes empty, we go up another
  2345.  * block, and so on, up to the root if necessary.
  2346.  * The line counts in the pointer blocks have already been adjusted by
  2347.  * ml_find_line().
  2348.  */
  2349.     if (count == 1)
  2350.     {
  2351.     mf_free(mfp, hp);    /* free the data block */
  2352.     buf->b_ml.ml_locked = NULL;
  2353.  
  2354.     for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0; --stack_idx)
  2355.     {
  2356.         buf->b_ml.ml_stack_top = 0;        /* stack is invalid when failing */
  2357.         ip = &(buf->b_ml.ml_stack[stack_idx]);
  2358.         idx = ip->ip_index;
  2359.         if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
  2360.         return FAIL;
  2361.         pp = (PTR_BL *)(hp->bh_data);   /* must be pointer block */
  2362.         if (pp->pb_id != PTR_ID)
  2363.         {
  2364.         EMSG("pointer block id wrong 4");
  2365.         mf_put(mfp, hp, FALSE, FALSE);
  2366.         return FAIL;
  2367.         }
  2368.         count = --(pp->pb_count);
  2369.         if (count == 0)        /* the pointer block becomes empty! */
  2370.         mf_free(mfp, hp);
  2371.         else
  2372.         {
  2373.         if (count != idx)    /* move entries after the deleted one */
  2374.             vim_memmove(&pp->pb_pointer[idx], &pp->pb_pointer[idx + 1],
  2375.                       (size_t)(count - idx) * sizeof(PTR_EN));
  2376.         mf_put(mfp, hp, TRUE, FALSE);
  2377.  
  2378.         buf->b_ml.ml_stack_top = stack_idx;    /* truncate stack */
  2379.             /* fix line count for rest of blocks in the stack */
  2380.         if (buf->b_ml.ml_locked_lineadd)
  2381.         {
  2382.             ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
  2383.             buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
  2384.                         buf->b_ml.ml_locked_lineadd;
  2385.         }
  2386.         ++(buf->b_ml.ml_stack_top);
  2387.  
  2388.         return OK;
  2389.         }
  2390.     }
  2391.     CHECK(1, "deleted block 1?");
  2392.  
  2393.     return OK;
  2394.     }
  2395.  
  2396.     /*
  2397.      * delete the text by moving the next lines forwards
  2398.      */
  2399.     text_start = dp->db_txt_start;
  2400.     line_start = ((dp->db_index[idx]) & DB_INDEX_MASK);
  2401.     if (idx == 0)        /* first line in block, text at the end */
  2402.     line_size = dp->db_txt_end - line_start;
  2403.     else
  2404.     line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start;
  2405.     vim_memmove((char *)dp + text_start + line_size, (char *)dp + text_start,
  2406.                        (size_t)(line_start - text_start));
  2407.  
  2408.     /*
  2409.      * delete the index by moving the next indexes backwards
  2410.      * Adjust the indexes for the text movement.
  2411.      */
  2412.     for (i = idx; i < count - 1; ++i)
  2413.     dp->db_index[i] = dp->db_index[i + 1] + line_size;
  2414.  
  2415.     dp->db_free += line_size + INDEX_SIZE;
  2416.     dp->db_txt_start += line_size;
  2417.     --(dp->db_line_count);
  2418.  
  2419.     /*
  2420.      * mark the block dirty and make sure it is in the file (for recovery)
  2421.      */
  2422.     buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
  2423.  
  2424.     return OK;
  2425. }
  2426.  
  2427. /*
  2428.  * set the B_MARKED flag for line 'lnum'
  2429.  */
  2430.     void
  2431. ml_setmarked(lnum)
  2432.     linenr_t lnum;
  2433. {
  2434.     BHDR    *hp;
  2435.     DATA_BL *dp;
  2436.                     /* invalid line number */
  2437.     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count ||
  2438.                         curbuf->b_ml.ml_mfp == NULL)
  2439.     return;                /* give error message? */
  2440.  
  2441.     if (lowest_marked == 0 || lowest_marked > lnum)
  2442.     lowest_marked = lnum;
  2443.  
  2444.     /*
  2445.      * find the data block containing the line
  2446.      * This also fills the stack with the blocks from the root to the data block
  2447.      * This also releases any locked block.
  2448.      */
  2449.     if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
  2450.     return;            /* give error message? */
  2451.  
  2452.     dp = (DATA_BL *)(hp->bh_data);
  2453.     dp->db_index[lnum - curbuf->b_ml.ml_locked_low] |= DB_MARKED;
  2454.     curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
  2455. }
  2456.  
  2457. /*
  2458.  * find the first line with its B_MARKED flag set
  2459.  */
  2460.     linenr_t
  2461. ml_firstmarked()
  2462. {
  2463.     BHDR    *hp;
  2464.     DATA_BL    *dp;
  2465.     linenr_t    lnum;
  2466.     int        i;
  2467.  
  2468.     if (curbuf->b_ml.ml_mfp == NULL)
  2469.     return (linenr_t) 0;
  2470.  
  2471.     /*
  2472.      * The search starts with lowest_marked line. This is the last line where
  2473.      * a mark was found, adjusted by inserting/deleting lines.
  2474.      */
  2475.     for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
  2476.     {
  2477.     /*
  2478.      * Find the data block containing the line.
  2479.      * This also fills the stack with the blocks from the root to the data
  2480.      * block This also releases any locked block.
  2481.      */
  2482.     if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
  2483.         return (linenr_t)0;            /* give error message? */
  2484.  
  2485.     dp = (DATA_BL *)(hp->bh_data);
  2486.  
  2487.     for (i = lnum - curbuf->b_ml.ml_locked_low;
  2488.                 lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
  2489.         if ((dp->db_index[i]) & DB_MARKED)
  2490.         {
  2491.         (dp->db_index[i]) &= DB_INDEX_MASK;
  2492.         curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
  2493.         lowest_marked = lnum + 1;
  2494.         return lnum;
  2495.         }
  2496.     }
  2497.  
  2498.     return (linenr_t) 0;
  2499. }
  2500.  
  2501. /*
  2502.  * return TRUE if line 'lnum' has a mark
  2503.  */
  2504.     int
  2505. ml_has_mark(lnum)
  2506.     linenr_t    lnum;
  2507. {
  2508.     BHDR    *hp;
  2509.     DATA_BL    *dp;
  2510.  
  2511.     if (curbuf->b_ml.ml_mfp == NULL ||
  2512.             (hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
  2513.     return FALSE;
  2514.  
  2515.     dp = (DATA_BL *)(hp->bh_data);
  2516.     return (int)((dp->db_index[lnum - curbuf->b_ml.ml_locked_low]) & DB_MARKED);
  2517. }
  2518.  
  2519. /*
  2520.  * clear all DB_MARKED flags
  2521.  */
  2522.     void
  2523. ml_clearmarked()
  2524. {
  2525.     BHDR    *hp;
  2526.     DATA_BL    *dp;
  2527.     linenr_t    lnum;
  2528.     int        i;
  2529.  
  2530.     if (curbuf->b_ml.ml_mfp == NULL)        /* nothing to do */
  2531.     return;
  2532.  
  2533.     /*
  2534.      * The search starts with line lowest_marked.
  2535.      */
  2536.     for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
  2537.     {
  2538.     /*
  2539.      * Find the data block containing the line.
  2540.      * This also fills the stack with the blocks from the root to the data
  2541.      * block and releases any locked block.
  2542.      */
  2543.     if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
  2544.         return;        /* give error message? */
  2545.  
  2546.     dp = (DATA_BL *)(hp->bh_data);
  2547.  
  2548.     for (i = lnum - curbuf->b_ml.ml_locked_low;
  2549.                 lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
  2550.         if ((dp->db_index[i]) & DB_MARKED)
  2551.         {
  2552.         (dp->db_index[i]) &= DB_INDEX_MASK;
  2553.         curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
  2554.         }
  2555.     }
  2556.  
  2557.     lowest_marked = 0;
  2558.     return;
  2559. }
  2560.  
  2561. /*
  2562.  * flush ml_line if necessary
  2563.  */
  2564.     static void
  2565. ml_flush_line(buf)
  2566.     BUF        *buf;
  2567. {
  2568.     BHDR    *hp;
  2569.     DATA_BL    *dp;
  2570.     linenr_t    lnum;
  2571.     char_u    *new_line;
  2572.     char_u    *old_line;
  2573.     colnr_t    new_len;
  2574.     int        old_len;
  2575.     int        extra;
  2576.     int        idx;
  2577.     int        start;
  2578.     int        count;
  2579.     int        i;
  2580.  
  2581.     if (buf->b_ml.ml_line_lnum == 0 ||
  2582.             buf->b_ml.ml_mfp == NULL)    /* nothing to do */
  2583.     return;
  2584.  
  2585.     if (buf->b_ml.ml_flags & ML_LINE_DIRTY)
  2586.     {
  2587.     lnum = buf->b_ml.ml_line_lnum;
  2588.     new_line = buf->b_ml.ml_line_ptr;
  2589.  
  2590.     hp = ml_find_line(buf, lnum, ML_FIND);
  2591.     if (hp == NULL)
  2592.         EMSGN("Cannot find line %ld", lnum);
  2593.     else
  2594.     {
  2595.         dp = (DATA_BL *)(hp->bh_data);
  2596.         idx = lnum - buf->b_ml.ml_locked_low;
  2597.         start = ((dp->db_index[idx]) & DB_INDEX_MASK);
  2598.         old_line = (char_u *)dp + start;
  2599.         if (idx == 0)    /* line is last in block */
  2600.         old_len = dp->db_txt_end - start;
  2601.         else        /* text of previous line follows */
  2602.         old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start;
  2603.         new_len = STRLEN(new_line) + 1;
  2604.         extra = new_len - old_len;        /* negative if lines gets smaller */
  2605.  
  2606.         /*
  2607.          * if new line fits in data block, replace directly
  2608.          */
  2609.         if ((int)dp->db_free >= extra)
  2610.         {
  2611.         /* if the length changes and there are following lines */
  2612.         count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
  2613.         if (extra != 0 && idx < count - 1)
  2614.         {
  2615.             /* move text of following lines */
  2616.             vim_memmove((char *)dp + dp->db_txt_start - extra,
  2617.                 (char *)dp + dp->db_txt_start,
  2618.                 (size_t)(start - dp->db_txt_start));
  2619.  
  2620.             /* adjust pointers of this and following lines */
  2621.             for (i = idx + 1; i < count; ++i)
  2622.             dp->db_index[i] -= extra;
  2623.         }
  2624.         dp->db_index[idx] -= extra;
  2625.  
  2626.         /* adjust free space */
  2627.         dp->db_free -= extra;
  2628.         dp->db_txt_start -= extra;
  2629.  
  2630.         /* copy new line into the data block */
  2631.         vim_memmove(old_line - extra, new_line, (size_t)new_len);
  2632.         buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
  2633.         }
  2634.         else
  2635.         {
  2636.         /*
  2637.          * Cannot do it in one data block: Delete and append.
  2638.          * Append first, because ml_delete_int() cannot delete the
  2639.          * last line in a buffer, which causes trouble for a buffer
  2640.          * that has only one line.
  2641.          * Don't forget to copy the mark!
  2642.          */
  2643.         /* How about handling errors??? */
  2644.         (void)ml_append_int(buf, lnum, new_line, new_len, FALSE,
  2645.                          (dp->db_index[idx] & DB_MARKED));
  2646.         (void)ml_delete_int(buf, lnum, FALSE);
  2647.         }
  2648.     }
  2649.     vim_free(new_line);
  2650.     }
  2651.  
  2652.     buf->b_ml.ml_line_lnum = 0;
  2653. }
  2654.  
  2655. /*
  2656.  * create a new, empty, data block
  2657.  */
  2658.     static BHDR *
  2659. ml_new_data(mfp, negative, page_count)
  2660.     MEMFILE    *mfp;
  2661.     int        negative;
  2662.     int        page_count;
  2663. {
  2664.     BHDR    *hp;
  2665.     DATA_BL    *dp;
  2666.  
  2667.     if ((hp = mf_new(mfp, negative, page_count)) == NULL)
  2668.     return NULL;
  2669.  
  2670.     dp = (DATA_BL *)(hp->bh_data);
  2671.     dp->db_id = DATA_ID;
  2672.     dp->db_txt_start = dp->db_txt_end = page_count * mfp->mf_page_size;
  2673.     dp->db_free = dp->db_txt_start - HEADER_SIZE;
  2674.     dp->db_line_count = 0;
  2675.  
  2676.     return hp;
  2677. }
  2678.  
  2679. /*
  2680.  * create a new, empty, pointer block
  2681.  */
  2682.     static BHDR *
  2683. ml_new_ptr(mfp)
  2684.     MEMFILE    *mfp;
  2685. {
  2686.     BHDR    *hp;
  2687.     PTR_BL    *pp;
  2688.  
  2689.     if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
  2690.     return NULL;
  2691.  
  2692.     pp = (PTR_BL *)(hp->bh_data);
  2693.     pp->pb_id = PTR_ID;
  2694.     pp->pb_count = 0;
  2695.     pp->pb_count_max = (mfp->mf_page_size - sizeof(PTR_BL)) / sizeof(PTR_EN) + 1;
  2696.  
  2697.     return hp;
  2698. }
  2699.  
  2700. /*
  2701.  * lookup line 'lnum' in a memline
  2702.  *
  2703.  *   action: if ML_DELETE or ML_INSERT the line count is updated while searching
  2704.  *         if ML_FLUSH only flush a locked block
  2705.  *         if ML_FIND just find the line
  2706.  *
  2707.  * If the block was found it is locked and put in ml_locked.
  2708.  * The stack is updated to lead to the locked block. The ip_high field in
  2709.  * the stack is updated to reflect the last line in the block AFTER the
  2710.  * insert or delete, also if the pointer block has not been updated yet. But
  2711.  * if if ml_locked != NULL ml_locked_lineadd must be added to ip_high.
  2712.  *
  2713.  * return: NULL for failure, pointer to block header otherwise
  2714.  */
  2715.     static BHDR *
  2716. ml_find_line(buf, lnum, action)
  2717.     BUF        *buf;
  2718.     linenr_t    lnum;
  2719.     int        action;
  2720. {
  2721.     DATA_BL    *dp;
  2722.     PTR_BL    *pp;
  2723.     IPTR    *ip;
  2724.     BHDR    *hp;
  2725.     MEMFILE    *mfp;
  2726.     linenr_t    t;
  2727.     blocknr_t    bnum, bnum2;
  2728.     int        dirty;
  2729.     linenr_t    low, high;
  2730.     int        top;
  2731.     int        page_count;
  2732.     int        idx;
  2733.  
  2734.     mfp = buf->b_ml.ml_mfp;
  2735.  
  2736.     /*
  2737.      * If there is a locked block check if the wanted line is in it.
  2738.      * If not, flush and release the locked block.
  2739.      * Don't do this for ML_INSERT_SAME, because the stack need to be updated.
  2740.      * Don't do this for ML_FLUSH, because we want to flush the locked block.
  2741.      */
  2742.     if (buf->b_ml.ml_locked)
  2743.     {
  2744.     if (ML_SIMPLE(action) && buf->b_ml.ml_locked_low <= lnum &&
  2745.                     buf->b_ml.ml_locked_high >= lnum)
  2746.     {
  2747.         /* remember to update pointer blocks and stack later */
  2748.         if (action == ML_INSERT)
  2749.         {
  2750.         ++(buf->b_ml.ml_locked_lineadd);
  2751.         ++(buf->b_ml.ml_locked_high);
  2752.         }
  2753.         else if (action == ML_DELETE)
  2754.         {
  2755.         --(buf->b_ml.ml_locked_lineadd);
  2756.         --(buf->b_ml.ml_locked_high);
  2757.         }
  2758.         return (buf->b_ml.ml_locked);
  2759.     }
  2760.  
  2761.     mf_put(mfp, buf->b_ml.ml_locked, buf->b_ml.ml_flags & ML_LOCKED_DIRTY,
  2762.                         buf->b_ml.ml_flags & ML_LOCKED_POS);
  2763.     buf->b_ml.ml_locked = NULL;
  2764.  
  2765.         /*
  2766.          * if lines have been added or deleted in the locked block, need to
  2767.          * update the line count in pointer blocks
  2768.          */
  2769.     if (buf->b_ml.ml_locked_lineadd)
  2770.         ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
  2771.     }
  2772.  
  2773.     if (action == ML_FLUSH)        /* nothing else to do */
  2774.     return NULL;
  2775.  
  2776.     bnum = 1;                /* start at the root of the tree */
  2777.     page_count = 1;
  2778.     low = 1;
  2779.     high = buf->b_ml.ml_line_count;
  2780.  
  2781.     if (action == ML_FIND)    /* first try stack entries */
  2782.     {
  2783.     for (top = buf->b_ml.ml_stack_top - 1; top >= 0; --top)
  2784.     {
  2785.         ip = &(buf->b_ml.ml_stack[top]);
  2786.         if (ip->ip_low <= lnum && ip->ip_high >= lnum)
  2787.         {
  2788.         bnum = ip->ip_bnum;
  2789.         low = ip->ip_low;
  2790.         high = ip->ip_high;
  2791.         buf->b_ml.ml_stack_top = top;    /* truncate stack at prev entry */
  2792.         break;
  2793.         }
  2794.     }
  2795.     if (top < 0)
  2796.         buf->b_ml.ml_stack_top = 0;        /* not found, start at the root */
  2797.     }
  2798.     else    /* ML_DELETE or ML_INSERT */
  2799.     buf->b_ml.ml_stack_top = 0;    /* start at the root */
  2800.  
  2801. /*
  2802.  * search downwards in the tree until a data block is found
  2803.  */
  2804.     for (;;)
  2805.     {
  2806.     if ((hp = mf_get(mfp, bnum, page_count)) == NULL)
  2807.         goto error_noblock;
  2808.  
  2809.     /*
  2810.      * update high for insert/delete
  2811.      */
  2812.     if (action == ML_INSERT)
  2813.         ++high;
  2814.     else if (action == ML_DELETE)
  2815.         --high;
  2816.  
  2817.     dp = (DATA_BL *)(hp->bh_data);
  2818.     if (dp->db_id == DATA_ID)    /* data block */
  2819.     {
  2820.         buf->b_ml.ml_locked = hp;
  2821.         buf->b_ml.ml_locked_low = low;
  2822.         buf->b_ml.ml_locked_high = high;
  2823.         buf->b_ml.ml_locked_lineadd = 0;
  2824.         buf->b_ml.ml_flags &= ~(ML_LOCKED_DIRTY | ML_LOCKED_POS);
  2825.         return hp;
  2826.     }
  2827.  
  2828.     pp = (PTR_BL *)(dp);        /* must be pointer block */
  2829.     if (pp->pb_id != PTR_ID)
  2830.     {
  2831.         EMSG("pointer block id wrong");
  2832.         goto error_block;
  2833.     }
  2834.  
  2835.     if ((top = ml_add_stack(buf)) < 0)    /* add new entry to stack */
  2836.         goto error_block;
  2837.     ip = &(buf->b_ml.ml_stack[top]);
  2838.     ip->ip_bnum = bnum;
  2839.     ip->ip_low = low;
  2840.     ip->ip_high = high;
  2841.     ip->ip_index = -1;        /* index not known yet */
  2842.  
  2843.     dirty = FALSE;
  2844.     for (idx = 0; idx < (int)pp->pb_count; ++idx)
  2845.     {
  2846.         t = pp->pb_pointer[idx].pe_line_count;
  2847.         CHECK(t == 0, "pe_line_count is zero");
  2848.         if ((low += t) > lnum)
  2849.         {
  2850.         ip->ip_index = idx;
  2851.         bnum = pp->pb_pointer[idx].pe_bnum;
  2852.         page_count = pp->pb_pointer[idx].pe_page_count;
  2853.         high = low - 1;
  2854.         low -= t;
  2855.  
  2856.         /*
  2857.          * a negative block number may have been changed
  2858.          */
  2859.         if (bnum < 0)
  2860.         {
  2861.             bnum2 = mf_trans_del(mfp, bnum);
  2862.             if (bnum != bnum2)
  2863.             {
  2864.             bnum = bnum2;
  2865.             pp->pb_pointer[idx].pe_bnum = bnum;
  2866.             dirty = TRUE;
  2867.             }
  2868.         }
  2869.  
  2870.         break;
  2871.         }
  2872.     }
  2873.     if (idx >= (int)pp->pb_count)        /* past the end: something wrong! */
  2874.     {
  2875.         if (lnum > buf->b_ml.ml_line_count)
  2876.         EMSGN("line number out of range: %ld past the end",
  2877.                           lnum - buf->b_ml.ml_line_count);
  2878.  
  2879.         else
  2880.         EMSGN("line count wrong in block %ld", bnum);
  2881.         goto error_block;
  2882.     }
  2883.     if (action == ML_DELETE)
  2884.     {
  2885.         pp->pb_pointer[idx].pe_line_count--;
  2886.         dirty = TRUE;
  2887.     }
  2888.     else if (action == ML_INSERT)
  2889.     {
  2890.         pp->pb_pointer[idx].pe_line_count++;
  2891.         dirty = TRUE;
  2892.     }
  2893.     mf_put(mfp, hp, dirty, FALSE);
  2894.     }
  2895.  
  2896. error_block:
  2897.     mf_put(mfp, hp, FALSE, FALSE);
  2898. error_noblock:
  2899. /*
  2900.  * If action is ML_DELETE or ML_INSERT we have to correct the tree for
  2901.  * the incremented/decremented line counts, because there won't be a line
  2902.  * inserted/deleted after all.
  2903.  */
  2904.     if (action == ML_DELETE)
  2905.     ml_lineadd(buf, 1);
  2906.     else if (action == ML_INSERT)
  2907.     ml_lineadd(buf, -1);
  2908.     buf->b_ml.ml_stack_top = 0;
  2909.     return NULL;
  2910. }
  2911.  
  2912. /*
  2913.  * add an entry to the info pointer stack
  2914.  *
  2915.  * return -1 for failure, number of the new entry otherwise
  2916.  */
  2917.     static int
  2918. ml_add_stack(buf)
  2919.     BUF        *buf;
  2920. {
  2921.     int        top;
  2922.     IPTR    *newstack;
  2923.  
  2924.     top = buf->b_ml.ml_stack_top;
  2925.  
  2926.     /* may have to increase the stack size */
  2927.     if (top == buf->b_ml.ml_stack_size)
  2928.     {
  2929.     CHECK(top > 0, "Stack size increases");    /* more than 5 levels??? */
  2930.  
  2931.     newstack = (IPTR *)alloc((unsigned)sizeof(IPTR) *
  2932.                     (buf->b_ml.ml_stack_size + STACK_INCR));
  2933.     if (newstack == NULL)
  2934.         return -1;
  2935.     vim_memmove(newstack, buf->b_ml.ml_stack, (size_t)top * sizeof(IPTR));
  2936.     vim_free(buf->b_ml.ml_stack);
  2937.     buf->b_ml.ml_stack = newstack;
  2938.     buf->b_ml.ml_stack_size += STACK_INCR;
  2939.     }
  2940.  
  2941.     buf->b_ml.ml_stack_top++;
  2942.     return top;
  2943. }
  2944.  
  2945. /*
  2946.  * Update the pointer blocks on the stack for inserted/deleted lines.
  2947.  * The stack itself is also updated.
  2948.  *
  2949.  * When a insert/delete line action fails, the line is not inserted/deleted,
  2950.  * but the pointer blocks have already been updated. That is fixed here by
  2951.  * walking through the stack.
  2952.  *
  2953.  * Count is the number of lines added, negative if lines have been deleted.
  2954.  */
  2955.     static void
  2956. ml_lineadd(buf, count)
  2957.     BUF        *buf;
  2958.     int        count;
  2959. {
  2960.     int        idx;
  2961.     IPTR    *ip;
  2962.     PTR_BL    *pp;
  2963.     MEMFILE    *mfp = buf->b_ml.ml_mfp;
  2964.     BHDR    *hp;
  2965.  
  2966.     for (idx = buf->b_ml.ml_stack_top - 1; idx >= 0; --idx)
  2967.     {
  2968.     ip = &(buf->b_ml.ml_stack[idx]);
  2969.     if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
  2970.         break;
  2971.     pp = (PTR_BL *)(hp->bh_data);    /* must be pointer block */
  2972.     if (pp->pb_id != PTR_ID)
  2973.     {
  2974.         mf_put(mfp, hp, FALSE, FALSE);
  2975.         EMSG("pointer block id wrong 2");
  2976.         break;
  2977.     }
  2978.     pp->pb_pointer[ip->ip_index].pe_line_count += count;
  2979.     ip->ip_high += count;
  2980.     mf_put(mfp, hp, TRUE, FALSE);
  2981.     }
  2982. }
  2983.  
  2984. /*
  2985.  * make swap file name out of the file name and a directory name
  2986.  */
  2987.     static char_u *
  2988. makeswapname(buf, dir_name)
  2989.     BUF        *buf;
  2990.     char_u  *dir_name;
  2991. {
  2992.     char_u    *r, *s;
  2993.  
  2994.     r = modname(buf->b_fname, (char_u *)
  2995. #ifdef VMS
  2996.         "_swp",
  2997. #else
  2998.         ".swp",
  2999. #endif
  3000. #ifdef SHORT_FNAME        /* always 8.3 file name */
  3001.         FALSE
  3002. #else
  3003.         /* Prepend a '.' to the swap file name for the current directory. */
  3004.         dir_name[0] == '.' && dir_name[1] == NUL
  3005. #endif
  3006.            );
  3007.     if (r == NULL)        /* out of memory */
  3008.     return NULL;
  3009.  
  3010.     s = get_file_in_dir(r, dir_name);
  3011.     vim_free(r);
  3012.     return s;
  3013. }
  3014.  
  3015. /*
  3016.  * Get file name to use for swap file or backup file.
  3017.  * Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir'
  3018.  * option "dname".
  3019.  * - If "dname" is ".", return "fname".
  3020.  * - If "dname" starts with "./", insert "dname" in "fname".
  3021.  * - Otherwise, prepend "dname" to the tail of "fname".
  3022.  *
  3023.  * The return value is an allocated string and can be NULL.
  3024.  */
  3025.     char_u *
  3026. get_file_in_dir(fname, dname)
  3027.     char_u  *fname;
  3028.     char_u  *dname;    /* don't use "dirname", it is a global for Alpha */
  3029. {
  3030.     char_u    *t;
  3031.     char_u    *tail;
  3032.     char_u    *retval;
  3033.     int        save_char;
  3034.  
  3035.     tail = gettail(fname);
  3036.  
  3037.     if (dname[0] == '.' && dname[1] == NUL)
  3038.     retval = vim_strsave(fname);
  3039.     else if (dname[0] == '.' && vim_ispathsep(dname[1]))
  3040.     {
  3041.     if (tail == fname)        /* no path before file name */
  3042.         retval = concat_fnames(dname + 2, tail, TRUE);
  3043.     else
  3044.     {
  3045.         save_char = *tail;
  3046.         *tail = NUL;
  3047.         t = concat_fnames(fname, dname + 2, TRUE);
  3048.         *tail = save_char;
  3049.         if (t == NULL)        /* out of memory */
  3050.         retval = NULL;
  3051.         else
  3052.         {
  3053.         retval = concat_fnames(t, tail, TRUE);
  3054.         vim_free(t);
  3055.         }
  3056.     }
  3057.     }
  3058.     else
  3059.     retval = concat_fnames(dname, tail, TRUE);
  3060.  
  3061.     return retval;
  3062. }
  3063.  
  3064. /*
  3065.  * Find out what name to use for the swap file for buffer 'buf'.
  3066.  *
  3067.  * Several names are tried to find one that does not exist
  3068.  *
  3069.  * Note: if BASENAMELEN is not correct, you will get error messages for
  3070.  *     not being able to open the swapfile
  3071.  */
  3072.     static char_u *
  3073. findswapname(buf, dirp, old_fname)
  3074.     BUF        *buf;
  3075.     char_u  **dirp;        /* pointer to list of directories */
  3076.     char_u  *old_fname;        /* don't give warning for this file name */
  3077. {
  3078.     char_u    *fname;
  3079.     int        n;
  3080.     time_t    x;
  3081.     char_u    *dir_name;
  3082.  
  3083. #ifdef AMIGA
  3084.     BPTR    fh;
  3085. #endif
  3086.  
  3087. #ifndef SHORT_FNAME
  3088.     int        r;
  3089.     FILE    *dummyfd = NULL;
  3090.  
  3091. /*
  3092.  * If we start editing a new file, e.g. "test.doc", which resides on an MSDOS
  3093.  * compatible filesystem, it is possible that the file "test.doc.swp" which we
  3094.  * create will be exactly the same file. To avoid this problem we temporarily
  3095.  * create "test.doc".
  3096.  * Don't do this for a symbolic link to a file that doesn't exist yet,
  3097.  * because the link would be deleted further on!
  3098.  */
  3099.     if (!(buf->b_p_sn || buf->b_shortname) && buf->b_fname &&
  3100.                         mch_getperm(buf->b_fname) < 0)
  3101.     {
  3102. # if defined(HAVE_LSTAT) && ((defined(S_IFMT) && defined(S_IFLNK)) || defined(S_ISLNK))
  3103.     struct stat st;
  3104.  
  3105.     if (lstat((char *)buf->b_fname, &st) == -1 ||
  3106. #  if defined(S_IFMT) && defined(S_IFLNK)
  3107.         (st.st_mode & S_IFMT) != S_IFLNK
  3108. #  else
  3109.         !S_ISLNK(st.st_mode)
  3110. #  endif
  3111.                             )
  3112. # endif
  3113.         dummyfd = fopen((char *)buf->b_fname, "w");
  3114.     }
  3115. #endif
  3116.  
  3117. /*
  3118.  * Isolate a directory name from *dirp and put it in dir_name.
  3119.  * First allocate some memory to put the directory name in.
  3120.  */
  3121.     dir_name = alloc((unsigned)STRLEN(*dirp) + 1);
  3122.     if (dir_name != NULL)
  3123.     (void)copy_option_part(dirp, dir_name, 31000, ",");
  3124.  
  3125. /*
  3126.  * we try different names until we find one that does not exist yet
  3127.  */
  3128.     if (dir_name == NULL)        /* out of memory */
  3129.     fname = NULL;
  3130.     else
  3131.     fname = makeswapname(buf, dir_name);
  3132.  
  3133.     for (;;)
  3134.     {
  3135.     if (fname == NULL)    /* must be out of memory */
  3136.         break;
  3137.     if ((n = STRLEN(fname)) == 0)    /* safety check */
  3138.     {
  3139.         vim_free(fname);
  3140.         fname = NULL;
  3141.         break;
  3142.     }
  3143. #if (defined(UNIX) || defined(OS2)) && !defined(ARCHIE) && !defined(SHORT_FNAME)
  3144. /*
  3145.  * Some systems have a MS-DOS compatible filesystem that use 8.3 character
  3146.  * file names. If this is the first try and the swap file name does not fit in
  3147.  * 8.3, detect if this is the case, set shortname and try again.
  3148.  */
  3149.     if (fname[n - 1] == 'p' && !(buf->b_p_sn || buf->b_shortname))
  3150.     {
  3151.         char_u        *tail;
  3152.         char_u        *fname2;
  3153.         struct stat        s1, s2;
  3154.         int            f1, f2;
  3155.         int            created1 = FALSE, created2 = FALSE;
  3156.         int            same = FALSE;
  3157.  
  3158.         /*
  3159.          * Check if swapfile name does not fit in 8.3:
  3160.          * It either contains two dots, is longer than 8 chars, or starts
  3161.          * with a dot.
  3162.          */
  3163.         tail = gettail(buf->b_fname);
  3164.         if (       vim_strchr(tail, '.') != NULL
  3165.             || STRLEN(tail) > (size_t)8
  3166.             || *gettail(fname) == '.')
  3167.         {
  3168.         fname2 = alloc(n + 2);
  3169.         if (fname2 != NULL)
  3170.         {
  3171.             STRCPY(fname2, fname);
  3172.             /* if fname == "xx.xx.swp",        fname2 = "xx.xx.swx"
  3173.              * if fname == ".xx.swp",        fname2 = ".xx.swpx"
  3174.              * if fname == "123456789.swp", fname2 = "12345678x.swp"
  3175.              */
  3176.             if (vim_strchr(tail, '.') != NULL)
  3177.             fname2[n - 1] = 'x';
  3178.             else if (*gettail(fname) == '.')
  3179.             {
  3180.             fname2[n] = 'x';
  3181.             fname2[n + 1] = NUL;
  3182.             }
  3183.             else
  3184.             fname2[n - 5] += 1;
  3185.             /*
  3186.              * may need to create the files to be able to use stat()
  3187.              */
  3188.             f1 = open((char *)fname, O_RDONLY | O_EXTRA);
  3189.             if (f1 < 0)
  3190.             {
  3191.             f1 = open((char *)fname, O_RDWR|O_CREAT|O_EXCL|O_EXTRA
  3192. #ifdef UNIX            /* open in rw------- mode */
  3193.                                   , (mode_t)0600
  3194. #endif
  3195. #if defined(MSDOS) || defined(WIN32) || defined(OS2)  /* open read/write */
  3196.                             , S_IREAD | S_IWRITE
  3197. #endif
  3198.                                         );
  3199. #if defined(OS2)
  3200.             if (f1 < 0 && errno == ENOENT)
  3201.                 same = TRUE;
  3202. #endif
  3203.             created1 = TRUE;
  3204.             }
  3205.             if (f1 >= 0)
  3206.             {
  3207.             f2 = open((char *)fname2, O_RDONLY | O_EXTRA);
  3208.             if (f2 < 0)
  3209.             {
  3210.                 f2 = open((char *)fname2,
  3211.                          O_RDWR|O_CREAT|O_EXCL|O_EXTRA
  3212. #ifdef UNIX            /* open in rw------- mode */
  3213.                                   , (mode_t)0600
  3214. #endif
  3215. #if defined(MSDOS) || defined(WIN32) || defined(OS2)  /* open read/write */
  3216.                             , S_IREAD | S_IWRITE
  3217. #endif
  3218.                                         );
  3219.                 created2 = TRUE;
  3220.             }
  3221.             if (f2 >= 0)
  3222.             {
  3223.                 /*
  3224.                  * Both files exist now. If stat() returns the
  3225.                  * same device and inode they are the same file.
  3226.                  */
  3227.                 if (fstat(f1, &s1) != -1 &&
  3228.                     fstat(f2, &s2) != -1 &&
  3229.                     s1.st_dev == s2.st_dev &&
  3230.                     s1.st_ino == s2.st_ino)
  3231.                 same = TRUE;
  3232.                 close(f2);
  3233.                 if (created2)
  3234.                 vim_remove(fname2);
  3235.             }
  3236.             close(f1);
  3237.             if (created1)
  3238.                 vim_remove(fname);
  3239.             }
  3240.             vim_free(fname2);
  3241.             if (same)
  3242.             {
  3243.             buf->b_shortname = TRUE;
  3244.             vim_free(fname);
  3245.             fname = makeswapname(buf, dir_name);
  3246.             continue;    /* try again with b_shortname set */
  3247.             }
  3248.         }
  3249.         }
  3250.     }
  3251. #endif
  3252.     /*
  3253.      * check if the swapfile already exists
  3254.      */
  3255.     if (mch_getperm(fname) < 0)    /* it does not exist */
  3256.     {
  3257. #ifdef AMIGA
  3258.         fh = Open((UBYTE *)fname, (long)MODE_NEWFILE);
  3259.         /*
  3260.          * on the Amiga mch_getperm() will return -1 when the file exists
  3261.          * but is being used by another program. This happens if you edit
  3262.          * a file twice.
  3263.          */
  3264.         if (fh != (BPTR)NULL)    /* can open file, OK */
  3265.         {
  3266.         Close(fh);
  3267.         break;
  3268.         }
  3269.         if (IoErr() != ERROR_OBJECT_IN_USE &&
  3270.                            IoErr() != ERROR_OBJECT_EXISTS)
  3271. #endif
  3272.         break;
  3273.     }
  3274.     /*
  3275.      * A file name equal to old_fname is OK to use.
  3276.      */
  3277.     if (old_fname != NULL && fnamecmp(fname, old_fname) == 0)
  3278.         break;
  3279.  
  3280.     /*
  3281.      * get here when file already exists
  3282.      */
  3283.     if (fname[n - 1] == 'p')    /* first try */
  3284.     {
  3285. #ifndef SHORT_FNAME
  3286.         /*
  3287.          * on MS-DOS compatible filesystems (e.g. messydos) file.doc.swp
  3288.          * and file.doc are the same file. To guess if this problem is
  3289.          * present try if file.doc.swx exists. If it does, we set
  3290.          * buf->b_shortname and try file_doc.swp (dots replaced by
  3291.          * underscores for this file), and try again. If it doesn't we
  3292.          * assume that "file.doc.swp" already exists.
  3293.          */
  3294.         if (!(buf->b_p_sn || buf->b_shortname))    /* not tried yet */
  3295.         {
  3296.         fname[n - 1] = 'x';
  3297.         r = mch_getperm(fname);        /* try "file.swx" */
  3298.         fname[n - 1] = 'p';
  3299.         if (r >= 0)            /* "file.swx" seems to exist */
  3300.         {
  3301.             buf->b_shortname = TRUE;
  3302.             vim_free(fname);
  3303.             fname = makeswapname(buf, dir_name);
  3304.             continue;        /* try again with '.' replaced by '_' */
  3305.         }
  3306.         }
  3307. #endif
  3308.         /*
  3309.          * If we get here the ".swp" file really exists.
  3310.          * Give an error message, unless recovering, no file name, we are
  3311.          * viewing a help file or when the path of the file is different
  3312.          * (happens when all .swp files are in one directory).
  3313.          */
  3314.         if (!recoverymode && buf->b_fname != NULL && !buf->b_help)
  3315.         {
  3316.         int        fd;
  3317.         struct block0    b0;
  3318.         int        differ = FALSE;
  3319.  
  3320.         /*
  3321.          * Try to read block 0 from the swap file to get the original
  3322.          * file name (and inode number).
  3323.          */
  3324.         fd = open((char *)fname, O_RDONLY | O_EXTRA);
  3325.         if (fd >= 0)
  3326.         {
  3327.             if (read(fd, (char *)&b0, sizeof(b0)) == sizeof(b0))
  3328.             {
  3329.             /*
  3330.              * The name in the swap file may be "~user/path/file".
  3331.              * Expand it first.
  3332.              */
  3333.             expand_env(b0.b0_fname, NameBuff, MAXPATHL);
  3334. #ifdef CHECK_INODE
  3335.             if (fnamecmp_ino(buf->b_ffname, NameBuff,
  3336.                              char_to_long(b0.b0_ino)))
  3337.                 differ = TRUE;
  3338. #else
  3339.             if (fnamecmp(NameBuff, buf->b_ffname) != 0)
  3340.                 differ = TRUE;
  3341. #endif
  3342.             }
  3343.             close(fd);
  3344.         }
  3345.  
  3346.         /* give the ATTENTION message when there is an old swap file
  3347.          * for the current file, and the buffer was not recovered. */
  3348.         if (differ == FALSE && !(curbuf->b_flags & BF_RECOVERED)
  3349.             && vim_strchr(p_shm, SHM_ATTENTION) == NULL)
  3350.         {
  3351.             struct stat st;
  3352.  
  3353.             ++no_wait_return;
  3354.             (void)EMSG("ATTENTION");
  3355.             MSG_PUTS("\nFound a swap file by the name \"");
  3356.             msg_home_replace(fname);
  3357.             MSG_PUTS("\"\n");
  3358.             swapfile_info(fname);
  3359.             MSG_PUTS("While opening file \"");
  3360.             msg_outtrans(buf->b_fname);
  3361.             MSG_PUTS("\"\n");
  3362.             if (stat((char *)buf->b_fname, &st) != -1)
  3363.             {
  3364.             MSG_PUTS("             dated: ");
  3365.             x = st.st_mtime;    /* Manx C can't do &st.st_mtime */
  3366.             MSG_PUTS(ctime(&x));
  3367.             }
  3368.             MSG_PUTS("\n(1) Another program may be editing the same file.\n");
  3369.             MSG_PUTS("    If this is the case, quit this edit session to avoid having\n");
  3370.             MSG_PUTS("    two different instances of the same file when making changes.\n");
  3371.             MSG_PUTS("\n(2) An edit session for this file crashed.\n");
  3372.             MSG_PUTS("    If this is the case, use \":recover\" or \"vim -r ");
  3373.             msg_outtrans(buf->b_fname);
  3374.             MSG_PUTS("\"\n    to recover the changes (see \":help recovery)\".\n");
  3375.             MSG_PUTS("    If you did this already, delete the swap file \"");
  3376.             msg_outtrans(fname);
  3377.             MSG_PUTS("\"\n    to avoid this message.\n\n");
  3378.             cmdline_row = msg_row;
  3379.             --no_wait_return;
  3380.             need_wait_return = TRUE;    /* call wait_return later */
  3381.         }
  3382.         }
  3383.     }
  3384.  
  3385.     if (fname[n - 1] == 'a')    /* tried enough names, give up */
  3386.     {
  3387.         vim_free(fname);
  3388.         fname = NULL;
  3389.         break;
  3390.     }
  3391.     --fname[n - 1];            /* change last char of the name */
  3392.     }
  3393.  
  3394.     vim_free(dir_name);
  3395. #ifndef SHORT_FNAME
  3396.     if (dummyfd)    /* file has been created temporarily */
  3397.     {
  3398.     fclose(dummyfd);
  3399.     vim_remove(buf->b_fname);
  3400.     }
  3401. #endif
  3402.     return fname;
  3403. }
  3404.  
  3405.     static int
  3406. b0_magic_wrong(b0p)
  3407.     ZERO_BL *b0p;
  3408. {
  3409.     return (b0p->b0_magic_long != (long)B0_MAGIC_LONG ||
  3410.         b0p->b0_magic_int != (int)B0_MAGIC_INT ||
  3411.         b0p->b0_magic_short != (short)B0_MAGIC_SHORT ||
  3412.         b0p->b0_magic_char != B0_MAGIC_CHAR);
  3413. }
  3414.  
  3415. #ifdef CHECK_INODE
  3416. /*
  3417.  * Compare current file name with file name from swap file.
  3418.  * Try to use inode numbers when possible.
  3419.  * Return non-zero when files are different.
  3420.  *
  3421.  * When comparing file names a few things have to be taken into consideration:
  3422.  * - When working over a network the full path of a file depends on the host.
  3423.  *   We check the inode number if possible.  It is not 100% reliable though,
  3424.  *   because the device number cannot be used over a network.
  3425.  * - When a file does not exist yet (editing a new file) there is no inode
  3426.  *   number.
  3427.  * - The file name in a swap file may not be valid on the current host.  The
  3428.  *   "~user" form is used whenever possible to avoid this.
  3429.  *
  3430.  * This is getting complicated, let's make a table:
  3431.  *
  3432.  *        ino_c  ino_s  fname_c  fname_s    differ =
  3433.  *
  3434.  * both files exist -> compare inode numbers:
  3435.  *        != 0   != 0    X     X    ino_c != ino_s
  3436.  *
  3437.  * inode number(s) unknown, file names available -> compare file names
  3438.  *        == 0    X    OK     OK    fname_c != fname_s
  3439.  *         X     == 0    OK     OK    fname_c != fname_s
  3440.  *
  3441.  * current file doesn't exist, file for swap file exist, file name(s) not
  3442.  * available -> probably different
  3443.  *        == 0   != 0    FAIL     X    TRUE
  3444.  *        == 0   != 0    X    FAIL    TRUE
  3445.  *
  3446.  * current file exists, inode for swap unknown, file name(s) not
  3447.  * available -> probably different
  3448.  *        != 0   == 0    FAIL     X    TRUE
  3449.  *        != 0   == 0    X    FAIL    TRUE
  3450.  *
  3451.  * current file doesn't exist, inode for swap unknown, one file name not
  3452.  * available -> probably different
  3453.  *        == 0   == 0    FAIL     OK    TRUE
  3454.  *        == 0   == 0    OK    FAIL    TRUE
  3455.  *
  3456.  * current file doesn't exist, inode for swap unknown, both file names not
  3457.  * available -> probably same file
  3458.  *        == 0   == 0    FAIL    FAIL    FALSE
  3459.  */
  3460.  
  3461.     static int
  3462. fnamecmp_ino(fname_c, fname_s, ino_block0)
  3463.     char_u    *fname_c;        /* current file name */
  3464.     char_u    *fname_s;        /* file name from swap file */
  3465.     long    ino_block0;
  3466. {
  3467.     struct stat    st;
  3468.     long    ino_c = 0;        /* ino of current file */
  3469.     long    ino_s;            /* ino of file from swap file */
  3470.     char_u    buf_c[MAXPATHL];    /* full path of fname_c */
  3471.     char_u    buf_s[MAXPATHL];    /* full path of fname_s */
  3472.     int        retval_c;        /* flag: buf_c valid */
  3473.     int        retval_s;        /* flag: buf_s valid */
  3474.  
  3475.  
  3476.     if (stat((char *)fname_c, &st) == 0)
  3477.     ino_c = st.st_ino;
  3478.  
  3479.     /*
  3480.      * First we try to get the inode from the file name, because the inode in
  3481.      * the swap file may be outdated.  If that fails (e.g. this path is not
  3482.      * valid on this machine), use the inode from block 0.
  3483.      */
  3484.     if (stat((char *)fname_s, &st) == 0)
  3485.     ino_s = st.st_ino;
  3486.     else
  3487.     ino_s = ino_block0;
  3488.  
  3489.     if (ino_c && ino_s)
  3490.     return (ino_c != ino_s);
  3491.  
  3492.     /*
  3493.      * One of the inode numbers is unknown, try a forced mch_FullName() and
  3494.      * compare the file names.
  3495.      */
  3496.     retval_c = mch_FullName(fname_c, buf_c, MAXPATHL, TRUE);
  3497.     retval_s = mch_FullName(fname_s, buf_s, MAXPATHL, TRUE);
  3498.     if (retval_c == OK && retval_s == OK)
  3499.     return (STRCMP(buf_c, buf_s) != 0);
  3500.  
  3501.     /*
  3502.      * Can't compare inodes or file names, guess that the files are different,
  3503.      * unless both appear not to exist at all.
  3504.      */
  3505.     if (ino_s == 0 && ino_c == 0 && retval_c == FAIL && retval_s == FAIL)
  3506.     return FALSE;
  3507.     return TRUE;
  3508. }
  3509. #endif /* CHECK_INODE */
  3510.  
  3511. /*
  3512.  * Move a long integer into a four byte character array.
  3513.  * Used for machine independency in block zero.
  3514.  */
  3515.     static void
  3516. long_to_char(n, s)
  3517.     long    n;
  3518.     char_u  *s;
  3519. {
  3520.     s[0] = (n & 0xff);
  3521.     n = (unsigned)n >> 8;
  3522.     s[1] = (n & 0xff);
  3523.     n = (unsigned)n >> 8;
  3524.     s[2] = (n & 0xff);
  3525.     n = (unsigned)n >> 8;
  3526.     s[3] = (n & 0xff);
  3527. }
  3528.  
  3529.     static long
  3530. char_to_long(s)
  3531.     char_u  *s;
  3532. {
  3533.     long    retval;
  3534.  
  3535.     retval = s[3];
  3536.     retval <<= 8;
  3537.     retval += s[2];
  3538.     retval <<= 8;
  3539.     retval += s[1];
  3540.     retval <<= 8;
  3541.     retval += s[0];
  3542.  
  3543.     return retval;
  3544. }
  3545.